activeldap-5.2.4/0000755000004100000410000000000013464071751013676 5ustar www-datawww-dataactiveldap-5.2.4/COPYING0000644000004100000410000004311013464071751014730 0ustar www-datawww-data GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. activeldap-5.2.4/test/0000755000004100000410000000000013464071751014655 5ustar www-datawww-dataactiveldap-5.2.4/test/add-phonetic-attribute-options-to-slapd.ldif0000644000004100000410000000065513464071751025275 0ustar www-datawww-data# Your LDAP server needs to accept 'phonetic' attribute option for test. # This is a LDIF file for OpenLDAP to do the configuration. # You can use this file by the following command linne on Debian GNU/Linux # or Ubuntu: # % sudo -H ldapmodify -Y EXTERNAL -H ldapi:/// -f test/add-phonetic-attribute-options-to-slapd.ldif version: 1 dn: cn=config changetype: modify add: olcAttributeOptions olcAttributeOptions: phonetic lang- activeldap-5.2.4/test/test_bind.rb0000644000004100000410000000330313464071751017154 0ustar www-datawww-datarequire 'al-test-utils' class TestBind < Test::Unit::TestCase include AlTestUtils::Config def setup super end def teardown ActiveLdap::Base.clear_active_connections! super end def test_anonymous assert(!ActiveLdap::Base.connected?) assert_nothing_raised do config = ActiveLdap::Base.configurations[LDAP_ENV].symbolize_keys config = ActiveLdap::Base.prepare_configuration(config) config.delete(:bind_dn) config[:allow_anonymous] = true connect(config) end assert(ActiveLdap::Base.connected?, "Checking is the connection was established.") end def test_bind assert(!ActiveLdap::Base.connected?) config = ActiveLdap::Base.configurations[LDAP_ENV].symbolize_keys config = ActiveLdap::Base.prepare_configuration(config) if config[:bind_dn].nil? and !config[:try_sasl] omit("need user configuration") end assert_nothing_raised do config[:allow_anonymous] = false connect(config) end assert(ActiveLdap::Base.connected?, "Checking is the connection was established.") assert(ActiveLdap::Base.connection.bound?) end def test_failed_bind assert(!ActiveLdap::Base.connected?) assert_raises(ActiveLdap::AuthenticationError) do config = ActiveLdap::Base.configurations[LDAP_ENV].symbolize_keys config = ActiveLdap::Base.prepare_configuration(config) config.delete(:bind_dn) config[:try_sasl] = false config[:allow_anonymous] = false connect(config) end assert(!ActiveLdap::Base.connection.bound?) end private def connect(config) ActiveLdap::Base.setup_connection(config) ActiveLdap::Base.connection.connect end end activeldap-5.2.4/test/test_entry.rb0000644000004100000410000000073313464071751017405 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestEntry < Test::Unit::TestCase include AlTestUtils def test_all make_temporary_group do |group| make_temporary_user do |user, password| all_entries = [ActiveLdap::Base.base] all_entries += [user.dn, user.base] all_entries += [group.dn, group.base] assert_equal(all_entries.sort, ActiveLdap::Entry.all.collect(&:dn).sort) end end end end activeldap-5.2.4/test/test_usermod-binary-del.rb0000644000004100000410000000414413464071751021746 0ustar www-datawww-datarequire 'al-test-utils' class TestUsermodBinaryDel < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "usermod-binary-del") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_user ensure_delete_user("test-user") do |uid,| assert(!@user_class.exists?(uid)) assert_equal([false, "User #{uid} doesn't exist.\n"], run_command(uid, "New CN", 11111)) assert(!@user_class.exists?(uid)) end end def test_modify_user make_temporary_user(:simple => true) do |user, password| user.add_class("strongAuthenticationUser") user.user_certificate = certificate assert_true(user.save) assert_usermod_binary_del_successfully(user.uid, "New #{user.cn}", user.uid_number.to_i + 100) end end private def assert_usermod_binary_del_successfully(name, cn, uid, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) previous_classes = @user_class.find(name).classes assert_operator(previous_classes, :include?, "strongAuthenticationUser") args.concat([name, cn, uid]) assert_equal([true, ""], run_command(*args, &block)) assert(@user_class.exists?(name)) user = @user_class.find(name) assert_equal(name, user.uid) assert_equal(cn, user.cn) assert_equal(uid.to_i, user.uid_number) assert_equal(uid.to_i, user.gid_number) assert_equal(uid.to_s, user.uid_number_before_type_cast) assert_equal(uid.to_s, user.gid_number_before_type_cast) assert_equal((previous_classes - ['strongAuthenticationUser']).sort, user.classes.sort) assert(!user.respond_to?(:user_certificate)) end end def assert_usermod_binary_del_failed(name, cn, uid, message, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([false, message], run_command(*args, &block)) assert(@user_class.exists?(name)) end end end activeldap-5.2.4/test/test_usermod-binary-add-time.rb0000644000004100000410000000413713464071751022670 0ustar www-datawww-datarequire 'al-test-utils' class TestUsermodBinaryAddTime < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "usermod-binary-add-time") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_user ensure_delete_user("test-user") do |uid,| assert(!@user_class.exists?(uid)) assert_equal([false, "User #{uid} doesn't exist.\n"], run_command(uid, "New CN", 11111)) assert(!@user_class.exists?(uid)) end end def test_modify_user make_temporary_user do |user, password| assert_usermod_binary_add_time_successfully(user.uid, "New #{user.cn}", user.uid_number.to_i + 100) end end private def assert_usermod_binary_add_time_successfully(name, cn, uid, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) previous_classes = @user_class.find(name).classes args.concat([name, cn, uid]) assert_equal([true, ""], run_command(*args, &block)) assert(@user_class.exists?(name)) user = @user_class.find(name) assert_equal(name, user.uid) assert_equal(cn, user.cn) assert_equal(uid.to_i, user.uid_number) assert_equal(uid.to_i, user.gid_number) assert_equal(uid.to_s, user.uid_number_before_type_cast) assert_equal(uid.to_s, user.gid_number_before_type_cast) assert_equal((previous_classes + ['strongAuthenticationUser']).sort, user.classes.sort) cert = File.read(File.join(@examples_dir, 'example.der')) cert.force_encoding("ascii-8bit") if cert.respond_to?(:force_encoding) assert_equal(cert, user.user_certificate) end end def assert_usermod_binary_add_time_failed(name, cn, uid, message, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([false, message], run_command(*args, &block)) assert(@user_class.exists?(name)) end end end activeldap-5.2.4/test/enable-start-tls.ldif0000644000004100000410000000160013464071751020673 0ustar www-datawww-data# Your LDAP server needs to support StartTLS when you test StartTLS related # feature. This is a LDIF file for OpenLDAP to do the configuration. # You can use this file by the following command linne on Debian GNU/Linux # or Ubuntu: # # % sudo usermod -a -G ssl-cert openldap # % sudo systemctl restart slapd # % sudo -H ldapmodify -Y EXTERNAL -H ldapi:/// -f test/enable-start-tls.ldif # # Adding the openldap user to the ssl-cert group is required to read # certification related files. version: 1 dn: cn=config delete: olcTLSCACertificateFile - add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/ca-certificates.crt - delete: olcTLSCertificateKeyFile - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ssl-cert-snakeoil.key - delete: olcTLSCertificateFile - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ssl-cert-snakeoil.pem activeldap-5.2.4/test/test_dn.rb0000644000004100000410000001270613464071751016650 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestDN < Test::Unit::TestCase include AlTestUtils def setup end def teardown end priority :must def test_parent dn = parse("o=xxx,dc=local,dc=net") assert_equal(parse("dc=local,dc=net"), dn.parent) assert_equal(parse("dc=net"), dn.parent.parent) assert_nil(dn.parent.parent.parent) end priority :normal def test_case_insensitive_dn_minus assert_dn_minus("dc=xxx", "dc=xxx,dc=LoCaL,dc=net", "dc=LOCAL,dc=net") end def test_dn_hash dn1 = ActiveLdap::DN.parse("o=xxx,dc=local,dc=net") dn2 = ActiveLdap::DN.parse("O = xxx , DC = local , DC = net") assert_equal(dn1.hash, dn2.hash) hash = {dn1 => :dn} assert_equal(:dn, hash[dn2]) end def test_dn_to_s assert_dn_to_s("dc=xxx,dc=local,dc=net", "dc = xxx, dc = \"local\",dc=net") assert_dn_to_s("dc=l\\,o\\=c\\+a\\,dc=\\#n\\;e\\\\t", "dc = \"l,o=c+a\" , dc=\"#n;e\\\\t\"") assert_dn_to_s("dc=\" l\\\"o c\\\\a l \",dc=\" n e t \"", "dc = \" l\\\"o c\\\\a l \" , dc= \\20n\\20e\\20t\\20") end def test_dn_minus assert_dn_minus("dc=xxx", "dc=xxx,dc=local,dc=net", "dc=local,dc=net") assert_dn_minus_raise("dc=xxx,dc=net", "dc=local,dc=net") end def test_parse_good_manner_dn assert_dn([["dc", "local"], ["dc", "net"]], "dc=local,dc=net") assert_dn([["dc", "net"]], "dc=net") assert_dn([], "") end def test_parse_dn_with_space assert_dn([["dc", "net"]], "dc =net") assert_dn([["dc", "net"]], "dc = net") assert_dn([["dc", "local"], ["dc", "net"]], "dc = local , dc = net") assert_dn([["dc", "local"], ["dc", "net "]], "dc = local , dc = net ") end def test_parse_dn_with_hex_pairs assert_dn([["dc", "local"], ["dc", "net"]], "dc = #6C6f63616C , dc = net") assert_dn([["dc", "lo cal "], ["dc", "net"]], "dc = #6C6f2063616C20 ,dc=net") end def test_parse_dn_with_quoted_attribute_value assert_dn([["dc", " l o c a l "], ["dc", "+n,\"e\";t"]], "dc = \" l o c a l \" , dc = \"+n,\\\"e\\\";t\"") end def test_parse_dn_with_spaces_in_attribute_value assert_dn([["o", "xxx "], ["dc", "local"]], "o=xxx\\ ,dc=local") assert_dn([["o", " xxx"], ["dc", "local"]], "o=\\ xxx,dc=local") assert_dn([["o", "xxx yyy"], ["dc", "local"]], "o=xxx\\ yyy,dc=local") assert_dn([["o", " xxx "], ["dc", "local"]], "o=\\ xxx\\ ,dc=local") end def test_parse_dn_in_rfc2253 assert_dn([ {"cn" => "Steve Kille"}, {"o" => "Isode Limited"}, {"c" => "GB"} ], "CN=Steve Kille,O=Isode Limited,C=GB") assert_dn([ {"ou" => "Sales", "cn" => "J. Smith"}, {"o" => "Widget Inc."}, {"c" => "US"}, ], "OU=Sales+CN=J. Smith,O=Widget Inc.,C=US") assert_dn([ {"cn" => "L. Eagle"}, {"o" => "Sue, Grabbit and Runn"}, {"c" => "GB"}, ], "CN=L. Eagle,O=Sue\\, Grabbit and Runn,C=GB") assert_dn([ {"cn" => "Before\rAfter"}, {"o" => "Test"}, {"c" => "GB"} ], "CN=Before\\0DAfter,O=Test,C=GB") assert_dn([ {"1.3.6.1.4.1.1466.0" => [0x04, 0x02, 0x48, 0x69].pack("C*")}, {"o" => "Test"}, {"c" => "GB"} ], "1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB") assert_dn([{"sn" => "Lučić"}], "SN=Lu\\C4\\8Di\\C4\\87") end def test_parse_invalid_dn assert_invalid_dn("attribute value is missing", "net") assert_invalid_dn("attribute value is missing", "local,dc=net") assert_invalid_dn("attribute value is missing", "dc=,dc=net") assert_invalid_dn("attribute type is missing", "=local,dc=net") assert_invalid_dn("name component is missing", ",dc=net") assert_invalid_dn("name component is missing", "dc=local,") assert_invalid_dn("found unmatched quotation", "dc=\"local") assert_invalid_dn("found unmatched quotation", "dc=\"loc\\al\"") end def test_parse_quoted_comma_dn assert_dn([["dc", "local,"]], "dc=local\\,") end def test_parser_collect_pairs assert_dn_parser_collect_pairs(",", "\\,") end private def assert_dn(expected, dn) assert_equal(ActiveLdap::DN.new(*expected), ActiveLdap::DN.parse(dn)) end def assert_invalid_dn(reason, dn) exception = nil assert_raise(ActiveLdap::DistinguishedNameInvalid) do begin ActiveLdap::DN.parse(dn) rescue Exception exception = $! raise end end assert_not_nil(exception) assert_equal(dn, exception.dn) assert_equal(_(reason), exception.reason) end def assert_dn_parser_collect_pairs(expected, source) parser = ActiveLdap::DN::Parser.new(source) assert_equal(expected, parser.send(:collect_pairs, StringScanner.new(source))) end def assert_dn_minus(expected, subtrahend, minuend) result = ActiveLdap::DN.parse(subtrahend) - ActiveLdap::DN.parse(minuend) assert_equal(ActiveLdap::DN.parse(expected), result) end def assert_dn_minus_raise(subtrahend, minuend) assert_raise(ArgumentError) do ActiveLdap::DN.parse(subtrahend) - ActiveLdap::DN.parse(minuend) end end def assert_dn_to_s(expected, dn) assert_equal(expected, ActiveLdap::DN.parse(dn).to_s) end def parse(dn) ActiveLdap::DN.parse(dn) end end activeldap-5.2.4/test/test_persistence.rb0000644000004100000410000000711613464071751020572 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestPersistence < Test::Unit::TestCase include AlTestUtils class TestDestroy < self class TestClass < self def test_by_dn make_temporary_user do |user,| assert(@user_class.exists?(user.uid)) @user_class.destroy(user.dn) assert(!@user_class.exists?(user.uid)) end end def test_by_dn_value make_temporary_user do |user,| assert(@user_class.exists?(user.dn)) @user_class.destroy(user.uid) assert(!@user_class.exists?(user.dn)) end end def test_by_dn_attribute make_temporary_user do |user,| assert(@user_class.exists?(user.dn)) @user_class.destroy("uid=#{user.uid}") assert(!@user_class.exists?(user.dn)) end end def test_multiple make_temporary_user do |user1,| make_temporary_user do |user2,| make_temporary_user do |user3,| assert(@user_class.exists?(user1.uid)) assert(@user_class.exists?(user2.uid)) assert(@user_class.exists?(user3.uid)) @user_class.destroy([user1.dn, user2.uid, "uid=#{user3.uid}"]) assert(!@user_class.exists?(user1.uid)) assert(!@user_class.exists?(user2.uid)) assert(!@user_class.exists?(user3.uid)) end end end end end class TestInstance < self def test_existence make_temporary_user do |user,| assert(@user_class.exists?(user.uid)) user.destroy assert(!@user_class.exists?(user.uid)) end end def test_frozen make_temporary_user do |user,| assert_false(user.frozen?) user.destroy assert_true(user.frozen?) end end end end class TestDelete < self class TestClass < self def test_by_dn make_temporary_user do |user,| assert(@user_class.exists?(user.uid)) @user_class.delete(user.dn) assert(!@user_class.exists?(user.uid)) end end def test_by_dn_value make_temporary_user do |user,| assert(@user_class.exists?(user.dn)) @user_class.delete(user.uid) assert(!@user_class.exists?(user.dn)) end end def test_by_dn_attribute make_temporary_user do |user,| assert(@user_class.exists?(user.dn)) @user_class.delete("uid=#{user.uid}") assert(!@user_class.exists?(user.dn)) end end def test_multiple make_temporary_user do |user1,| make_temporary_user do |user2,| make_temporary_user do |user3,| assert(@user_class.exists?(user1.uid)) assert(@user_class.exists?(user2.uid)) assert(@user_class.exists?(user3.uid)) @user_class.delete([user1.dn, user2.uid, "uid=#{user3.uid}"]) assert(!@user_class.exists?(user1.uid)) assert(!@user_class.exists?(user2.uid)) assert(!@user_class.exists?(user3.uid)) end end end end end class TestInstance < self def test_existence make_temporary_user do |user,| assert(@user_class.exists?(user.uid)) user.delete assert(!@user_class.exists?(user.uid)) end end def test_frozen make_temporary_user do |user,| assert_false(user.frozen?) user.delete assert_true(user.frozen?) end end end end end activeldap-5.2.4/test/fixtures/0000755000004100000410000000000013464071751016526 5ustar www-datawww-dataactiveldap-5.2.4/test/fixtures/lower_case_object_class_schema.rb0000644000004100000410000047124213464071751025243 0ustar www-datawww-data{"objectClasses"=> ["( 2.5.20.1 NAME 'subschema' AUXILIARY MAY ( ditstructurerules $ nameforms $ ditcontentrules $ objectclasses $ attributetypes $ matchingrules $ matchingruleuse ) )", "( 2.5.6.0 NAME 'top' ABSTRACT MUST objectclass )", "( 2.5.6.1 NAME 'alias' SUP top STRUCTURAL MUST aliasedobjectname )", "( 2.5.6.2 NAME 'country' SUP top STRUCTURAL MUST c MAY ( enhancedsearchguide $ description ) )", "( 2.5.6.3 NAME 'locality' SUP top STRUCTURAL MAY ( street $ seealso $ enhancedsearchguide $ st $ l $ description ) )", "( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL MUST o MAY ( userpassword $ enhancedsearchguide $ seealso $ businesscategory $ x121address $ registeredaddress $ destinationindicator $ preferreddeliverymethod $ telexnumber $ teletexterminalidentifier $ telephonenumber $ internationalisdnnumber $ facsimiletelephonenumber $ street $ postofficebox $ postalcode $ postaladdress $ physicaldeliveryofficename $ st $ l $ description ) )", "( 2.5.6.5 NAME 'organizationalunit' SUP top STRUCTURAL MUST ou MAY ( userpassword $ enhancedsearchguide $ seealso $ businesscategory $ x121address $ registeredaddress $ destinationindicator $ preferreddeliverymethod $ telexnumber $ teletexterminalidentifier $ telephonenumber $ internationalisdnnumber $ facsimiletelephonenumber $ street $ postofficebox $ postalcode $ postaladdress $ physicaldeliveryofficename $ st $ l $ description ) )", "( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn ) MAY ( userpassword $ telephonenumber $ seealso $ description ) )", "( 2.5.6.7 NAME 'organizationalperson' SUP person STRUCTURAL MAY ( title $ x121address $ registeredaddress $ destinationindicator $ preferreddeliverymethod $ telexnumber $ teletexterminalidentifier $ telephonenumber $ internationalisdnnumber $ facsimiletelephonenumber $ street $ postofficebox $ postalcode $ postaladdress $ physicaldeliveryofficename $ ou $ st $ l ) )", "( 2.5.6.8 NAME 'organizationalrole' SUP top STRUCTURAL MUST cn MAY ( x121address $ registeredaddress $ destinationindicator $ preferreddeliverymethod $ telexnumber $ teletexterminalidentifier $ telephonenumber $ internationalisdnnumber $ facsimiletelephonenumber $ seealso $ roleoccupant $ street $ postofficebox $ postalcode $ postaladdress $ physicaldeliveryofficename $ ou $ st $ l $ description ) )", "( 2.5.6.9 NAME 'groupofnames' SUP top STRUCTURAL MUST cn MAY ( member $ businesscategory $ seealso $ owner $ ou $ o $ description ) )", "( 2.5.6.11 NAME 'applicationprocess' SUP top STRUCTURAL MUST cn MAY ( seealso $ ou $ l $ description ) )", "( 2.5.6.12 NAME 'applicationentity' SUP top STRUCTURAL MUST ( presentationaddress $ cn ) MAY ( supportedapplicationcontext $ seealso $ ou $ o $ l $ description ) )", "( 2.5.6.13 NAME 'dsa' SUP applicationentity STRUCTURAL MAY knowledgeinformation )", "( 2.5.6.14 NAME 'device' SUP top STRUCTURAL MUST cn MAY ( serialnumber $ seealso $ owner $ ou $ o $ l $ description ) )", "( 2.5.6.15 NAME 'strongauthenticationuser' SUP top AUXILIARY MUST usercertificate )", "( 2.5.6.16 NAME 'certificationauthority' SUP top AUXILIARY MUST ( authorityrevocationlist $ certificaterevocationlist $ cacertificate ) MAY crosscertificatepair )", "( 2.5.6.17 NAME 'groupofuniquenames' SUP top STRUCTURAL MUST ( uniquemember $ cn ) MAY ( businesscategory $ seealso $ owner $ ou $ o $ description ) )", "( 2.5.6.18 NAME 'usersecurityinformation' SUP top AUXILIARY MAY supportedalgorithms )", "( 2.5.6.16.2 NAME 'certificationauthority-v2' SUP certificationauthority AUXILIARY MAY deltarevocationlist )", "( 2.5.6.19 NAME 'crldistributionpoint' SUP top STRUCTURAL MUST cn MAY ( certificaterevocationlist $ authorityrevocationlist $ deltarevocationlist ) )", "( 2.5.6.20 NAME 'dmd' SUP top STRUCTURAL MUST dmdname MAY ( userpassword $ enhancedsearchguide $ seealso $ businesscategory $ x121address $ registeredaddress $ destinationindicator $ preferreddeliverymethod $ telexnumber $ teletexterminalidentifier $ telephonenumber $ internationalisdnnumber $ facsimiletelephonenumber $ street $ postofficebox $ postalcode $ postaladdress $ physicaldeliveryofficename $ st $ l $ description ) )", "( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleobject' SUP top AUXILIARY )", "( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top STRUCTURAL MUST dc MAY ( userpassword $ enhancedsearchguide $ seealso $ businesscategory $ x121address $ registeredaddress $ destinationindicator $ preferreddeliverymethod $ telexnumber $ teletexterminalidentifier $ telephonenumber $ internationalisdnnumber $ facsimiletelephonenumber $ street $ postofficebox $ postalcode $ postaladdress $ physicaldeliveryofficename $ st $ l $ description $ o ) )", "( 1.3.6.1.4.1.1466.344 NAME 'dcobject' SUP top AUXILIARY MUST dc )", "( 2.16.840.1.113730.3.2.2 NAME 'inetorgperson' SUP organizationalperson STRUCTURAL MAY ( audio $ businesscategory $ carlicense $ departmentnumber $ displayname $ employeenumber $ employeetype $ givenname $ homephone $ homepostaladdress $ initials $ jpegphoto $ labeleduri $ mail $ manager $ mobile $ o $ pager $ photo $ roomnumber $ secretary $ uid $ usercertificate $ x500uniqueidentifier $ preferredlanguage $ usersmimecertificate $ userpkcs12 ) )", "( 2.16.840.1.113730.3.2.6 NAME 'referral' SUP top STRUCTURAL MAY ref )", "( 2.16.840.1.113719.2.142.6.1.1 NAME 'ldapsubentry' DESC 'LDAP Subentry class, version 1' SUP top STRUCTURAL MAY cn )", "( 1.3.6.1.4.1.2415.2.2.2.1 NAME 'scsubschema' DESC 'SWCOM subschema oc to store some more attributes in schema entry' SUP subschema AUXILIARY MAY scschemafiletimestamp )", "( 1.3.6.1.4.1.2415.2.2.2.2 NAME 'adminpolicy' SUP top STRUCTURAL MUST cn MAY ( adminattributeconstraint $ adminparentadminpolicy $ adminprovisiononly $ admintemplateonly $ description ) )", "( 1.3.6.1.4.1.2415.2.2.2.3 NAME 'adminroot' SUP top STRUCTURAL MUST cn MAY ( adminpolicydefaultdn $ adminallocrules ) )", "( 1.3.6.1.4.1.2415.2.2.2.4 NAME 'maildomain' SUP top AUXILIARY MUST ( domainname $ domaintype ) MAY ( mailrelayhost $ mailrewritedomain $ mailwildcardaccount ) )", "( 1.3.6.1.4.1.2415.2.2.2.8 NAME 'adminallocation' SUP top AUXILIARY MAY ( adminmaxrealms $ adminnumrealms $ adminmaxdomains $ adminnumdomains $ adminmaxmaildomains $ adminnummaildomains $ adminmaxorgs $ adminnumorgs $ adminmaxorgunits $ adminnumorgunits $ adminmaxusers $ adminnumusers $ adminmaxmailinglists $ adminnummailinglists $ adminmaxstoragekb $ adminusedstoragekb $ adminmaxsmtp $ adminnumsmtp $ adminmaxsmtpssl $ adminnumsmtpssl $ adminmaxpop $ adminnumpop $ adminmaxpopssl $ adminnumpopssl $ adminmaximap $ adminnumimap $ adminmaximapssl $ adminnumimapssl $ adminmaxselfcare $ adminnumselfcare $ adminmaxintermanager $ adminnumintermanager $ adminmaxwebmail $ adminnumwebmail $ adminmaxwebmailssl $ adminnumwebmailssl $ adminmaxmobilemail $ adminnummobilemail $ adminallocsubtots $ adminpolicydnused ) )", "( 1.3.6.1.4.1.2415.2.2.2.10 NAME 'adminrole' SUP top STRUCTURAL MUST ( cn $ adminaccesslevel ) MAY ( admincreaterealm $ admindeleterealm $ admincreatepeeradmingroup $ admindeletepeeradmingroup $ admincreatesubadmingroup $ admindeletesubadmingroup $ admincreatepeeradminpolicy $ admindeletepeeradminpolicy $ admincreatesubadminpolicy $ admindeletesubadminpolicy $ adminallowedcreateclasses $ adminallowedupdateclasses ) )", "( 1.3.6.1.4.1.2415.2.2.2.11 NAME 'admingroup' SUP groupofnames STRUCTURAL MUST adminroledn MAY ( adminalloweddomains $ adminallowedadminpolicydn $ adminparentdomains $ adminattributeconstraint $ adminallowedmessagestorehosts $ adminallowedautoreplyhosts $ adminsuperiorattributeconstraint $ contactinfo ) )", "( 1.3.6.1.4.1.2415.2.2.2.12 NAME 'maillocaluserprefs' SUP top AUXILIARY )", "( 1.3.6.1.4.1.2415.2.2.2.13 NAME 'scconfig' DESC 'Configuration object' SUP top STRUCTURAL MUST cn MAY scattributeindexinfo )", "( 1.3.6.1.4.1.2415.2.2.2.16 NAME 'partition' DESC 'Partition Definitions' SUP top STRUCTURAL MUST cn MAY partition )", "( 1.3.6.1.4.1.2415.2.2.2.17 NAME 'mailinglist' SUP top STRUCTURAL MUST ( cn $ mail $ listlocalsubscriptionoption $ listremotesubscriptionoption $ listsubscriptionmoderationmethod $ listverifysubscriberequest $ listunsubscriptionoption $ listunsubscriptionmoderationmethod $ listverifyunsubscriberequest $ listaccesssubscriberlistoption $ listsubscriberpostingoption $ listnonsubscriberpostingoption $ listpostingmoderationmethod $ listdetectrequest $ listdeliverymode $ listaddressexpansionstyle $ listquotamaxsubscribers $ listquotamaxmsgsizekb $ listquotamaxmsgsperday $ listquotamaxvolumekbperday ) MAY ( description $ listextendedlocaldomains $ listwelcomemessage $ listgoodbyemessage $ listprologuetext $ listepiloguetext $ listheaderstobeadded $ listheaderstoberemoved $ listheaderstorewrite $ listremovexheaders $ listapprovedposters $ listdigestvolumenumber $ listdigestissuenumber $ listdigestdeliverytime $ liststatsdeliverytime $ listlastdigestdelivery $ listlaststatsdelivery $ listmaxbouncespersubscriber $ liststatsmessages $ liststatsvolume $ liststatsnewsubscribers $ liststatsunsubscribers $ liststatsforcedunsubscribers $ liststatsmessageswaiting $ liststatssubscriberswaiting $ liststatsunsubscriberswaiting $ liststatisticsnotification $ listbouncenotification $ listoverlimitnotification $ listsuppressnotifications $ listdynamic $ listdynamicbase $ listdynamicfilter ) )", "( 1.3.6.1.4.1.2415.2.2.2.18 NAME 'mailinglistowner' SUP top STRUCTURAL MUST mail )", "( 1.3.6.1.4.1.2415.2.2.2.19 NAME 'mailinglistrequest' SUP top STRUCTURAL MUST mail )", "( 1.3.6.1.4.1.2415.2.2.2.20 NAME 'mailinglistsubscriber' SUP top STRUCTURAL MUST ( listsubscriberaddress $ listdeliverymode ) MAY ( liststatsmessages $ liststatsvolume $ liststatsbounces ) )", "( 1.3.6.1.4.1.2415.2.2.2.21 NAME 'adminuserprefs' SUP top AUXILIARY MAY ( labeleduri $ adminpreferredlocale $ adminlastlogin ) )", "( 1.3.6.1.4.1.2415.2.2.2.22 NAME 'adminrealmspec' SUP top STRUCTURAL MUST adminrealmtype MAY ( admindefaultcreatedgroups $ admintargetobjectclass $ admindomainspeccontrol $ adminminallowedaccesslevel ) )", "( 1.3.6.1.4.1.2415.2.2.2.23 NAME 'adminalloccounts' SUP top STRUCTURAL MUST cn )", "( 1.3.6.1.4.1.2415.2.2.2.24 NAME 'dseroot' SUP top STRUCTURAL MAY ( cn $ subschemasubentry $ changelog $ supportedldapversion $ firstchangenumber $ lastchangenumber $ lastexpirednumber $ firstentryid $ lastentryid $ supportedextension $ supportedcontrol ) )", "( 1.3.6.1.4.1.2415.2.60.2.1 NAME 'attridmap' DESC 'SWCOM oc to store attribute id to name mapping' AUXILIARY MUST attrid )", "( 1.3.6.1.4.1.2415.2.60.2.51 NAME 'msguser' SUP top AUXILIARY MAY ( mailboxid $ maillogin $ mailpassword $ mailpasswordtype $ mailboxstatus $ postaladdress $ postalcode $ msgsecretquestion $ msgsecretanswer ) )", "( 1.3.6.1.4.1.2415.2.60.2.52 NAME 'msguserprefs' SUP top AUXILIARY MAY ( msglocale $ msgcharset $ msgtimezone ) )", "( 1.3.6.1.4.1.2415.2.3.2.2 NAME 'addressbookdistlist' AUXILIARY MAY displayname )", "( 1.3.6.1.4.1.2415.2.3.2.3 NAME 'addressbookowner' AUXILIARY MAY addressbookdn )", "( 1.3.6.1.4.1.2415.7.55.2.1 NAME 'senderscontrol' SUP top STRUCTURAL MUST cn MAY ( mailapprovedsenderslist $ mailblockedsenderslist ) )", "( 1.3.6.1.4.1.2415.3.35.2.4 NAME 'umphone' SUP top STRUCTURAL MAY ( umivrflow $ umivrvariant ) )", "( 1.3.6.1.4.1.2415.3.35.2.7 NAME 'umdomain' SUP top AUXILIARY MAY ( umenableautoprovisioning $ umautoprovisioningkeys $ umautoprovisioningminkey $ umautoprovisioningmaxkey $ umautoprovisioningadminpolicydn $ umautoprovisioningmaildomain $ umautoprovisioningmaillogin $ umautoprovisioningmailprefix $ umautoprovisioningmss $ umautoprovisioningpassword $ umautoprovisioningpin $ umautoprovisioningtargetnumberallowlist $ umautoprovisioningnotifytypes ) )", "( 1.3.6.1.4.1.2415.774.767.2.1 NAME 'notifyuserprefs' DESC 'Notification Provisioning' SUP top AUXILIARY MAY ( notifydeleteemail $ notifybulkemail $ notifyfmtattchnone $ notifyfiltperuser $ notifybillingtype $ notifyservicelist $ notifyserviceoverride $ notifyattributelist $ notifyfmtrulegroupbasedn $ smsmin ) )", "( 1.3.6.1.4.1.2415.774.767.2.12 NAME 'notifyservice' DESC 'List of Event Types associated with the service' SUP top AUXILIARY MUST notifyfiltruleeventlist MAY description )", "( 1.3.6.1.4.1.2415.774.767.2.13 NAME 'notifyfilterrule' DESC 'Notification Filter Rule' SUP top STRUCTURAL MUST ( notifyfiltrulename $ notifyfiltrulescope ) MAY ( notifyfiltrulevalue $ notifyfiltprofile $ notifyfiltruleservice $ notifyfiltshareddn $ notifyfiltactive $ notifyfiltrulelanguage $ notifyfiltdefaultaction $ description ) )", "( 1.3.6.1.4.1.2415.774.767.2.14 NAME 'notifyruleset' DESC 'Notification Rule Set' SUP top STRUCTURAL MUST notifyrulesetname MAY description )", "( 1.3.6.1.4.1.2415.774.767.2.15 NAME 'notifyformatrule' DESC 'Notification Format Rule' SUP top STRUCTURAL MAY ( notifyfmtrulelocale $ notifyfmtrulevalue $ description ) )", "( 1.3.6.1.4.1.2415.774.767.2.16 NAME 'notifyfmtrulegroup' DESC 'Notification Format Rule Group' SUP top STRUCTURAL MUST ( notifyfmtrulegroupname $ notifyfmtrulegrouptype ) MAY ( notifyfmtrulegroupservice $ notifyfmtrulegroupntfntype $ notifyfmtrulegroupeventtype $ notifyfmtrulegroupdlvtype $ description ) )", "( 1.3.6.1.4.1.2415.2.3.2.1 NAME 'addressbookperson' SUP top STRUCTURAL MAY ( givenname $ sn $ nickname $ middlename $ mailprimaryaddress $ o $ departmentnumber $ title $ labeleduri $ telephonenumber $ mobile $ facsimiletelephonenumber $ pager $ otherphonenumber $ postaladdress $ worklink $ homepostaladdress $ birthday $ anniversary $ notes $ mailsecondaryaddress $ personaltitle $ displayname $ homephone $ homefacsimiletelephonenumber $ homemobile $ homepager $ homelink $ spousename $ gender $ childname $ usercertificate $ userpkcs12 $ jpegphoto $ buddyname $ improvider ) )", "( 1.3.6.1.4.1.2415.2.3.2.4 NAME 'corpaddressbookperson' SUP top AUXILIARY MUST corpmailprimaryaddress MAY ( givenname $ sn $ nickname $ middlename $ o $ departmentnumber $ title $ labeleduri $ telephonenumber $ mobile $ facsimiletelephonenumber $ pager $ otherphonenumber $ postaladdress $ worklink $ homepostaladdress $ birthday $ anniversary $ notes $ mailsecondaryaddress $ personaltitle $ displayname $ homephone $ homefacsimiletelephonenumber $ homemobile $ homepager $ homelink $ spousename $ gender $ childname $ usercertificate $ userpkcs12 $ jpegphoto $ buddyname $ improvider ) )", "( 1.3.6.1.4.1.2415.2.2.2.7 NAME 'adminrealm' SUP top STRUCTURAL MUST cn MAY ( billingid $ contactinfo $ adminpolicygrantdn $ adminattributeconstraint $ adminsuperiorattributeconstraint $ adminapprovedsenderslist $ adminblockedsenderslist $ adminparentalrejectaction $ adminparentalrejectinfo $ adminparentaldefaultdisposition $ adminbmimailwallspamactionverb $ admintargetdn $ corpaddressbookallowed $ corpaddressbookwanted $ adminfamilymaxusers $ adminfamilymaxstoragekb ) )", "( 1.3.6.1.4.1.2415.2.2.2.9 NAME 'admintarget' SUP top AUXILIARY MUST adminrealmdn MAY ( addressbookdn $ adminrealmspecdn ) )", "( 1.3.6.1.4.1.2415.8.2.1 NAME 'netmailuser' SUP top AUXILIARY MAY ( netmailautocollect $ netmailmsgsperpage $ netmailreplyformat $ netmaildefaulteditor $ netmailmsglistcols $ netmailautopopemail $ netmailpopemailacctselect $ netmailactivealias $ netmailpopacctdetails $ netmailabentriesperpage $ netmailenablevoice $ netmailenablefax $ netmailcurrentver $ netmailsendreturnreceipt $ netmobilemailabsortby $ netmobilemailabdisplayby $ netmailaddressbookcontactlistmax $ netmailmsgviewprivacyfilter $ netmailrequestreturnreceipt $ netmailautospellcheck $ netmailusetrash $ netmailsignaturebeforereply ) )", "( 1.3.6.1.4.1.2415.7.55.2.2 NAME 'metadata' SUP top STRUCTURAL MUST cn MAY metavalue )", "( 1.3.6.1.4.1.2415.2.2.2.14 NAME 'scconfigroot' DESC 'Configuration Root' SUP top STRUCTURAL MUST cn MAY ( sccachedirdbstatus $ lastentryid ) )", "( 2.5.6.10 NAME 'residentialperson' SUP person STRUCTURAL MUST l MAY ( businesscategory $ x121address $ registeredaddress $ destinationindicator $ preferreddeliverymethod $ telexnumber $ teletexterminalidentifier $ telephonenumber $ internationalisdnnumber $ facsimiletelephonenumber $ street $ postofficebox $ postalcode $ postaladdress $ physicaldeliveryofficename $ st ) )", "( 1.3.6.1.4.1.2415.3.35.2.3 NAME 'umphonenumber' SUP top AUXILIARY MAY ( umpn $ umpntype $ umpnstatus $ umpnlabel $ umpngreetings $ umpnlocale $ umid ) )", "( 1.3.6.1.4.1.2415.3.35.2.6 NAME 'umrealm' SUP top AUXILIARY MAY ( umdbnmaxnamestoprompt $ umdbnmindigitstoenter $ umrealmlocale $ umuserlocalelist $ umcallerlocalelist $ umemaillocalelist $ umdbnkeypad $ umdbnnameorder $ umivraccesslockperiod $ umoffsystemdeliveryoption ) )", "( 1.3.6.1.4.1.2415.3.35.2.8 NAME 'umabextension' SUP top AUXILIARY MUST umabentryid MAY ( umivrdefaultringbacktone $ umivravailringbacktones ) )", "( 1.3.6.1.4.1.2415.2.2.2.15 NAME 'replagreement' DESC 'Replication Agreement' SUP top STRUCTURAL MUST ( cn $ updateinterval ) MAY ( replarea $ supplierreference $ consumeridentity $ consumerpassword $ lastchangenumber $ lastupdatedtime $ updateintervalas100millisecs $ nextupdatetime $ lastlcnchgtime $ createhost $ masterserverrole ) )", "( 2.16.840.1.113730.3.2.1 NAME 'changelogentry' SUP top STRUCTURAL MUST ( changenumber $ targetdn $ changetype ) MAY ( changes $ newrdn $ deleteoldrdn $ newsuperior $ entry $ transactid $ createhost $ targetpartitionname ) )", "( 1.3.6.1.4.1.2415.3.35.2.5 NAME 'umspecialuserprefs' SUP top AUXILIARY MAY ( umivrcallerinputtype $ umivrenablebusyrnaoption $ umivrenablecallermenu $ umivrecpcallermenu $ umivrnumringsbeforetransfer $ umivrpoundkeycontrol $ umivrstarkeycontrol $ umivrstarkeymailbox $ umivrecpmaxnoinput $ umivrecpmaxnomatch $ umivrcallforwardingmethod $ umivrextensiontype $ umivrphoneextensionprefix $ umivrspecialmailboxtype $ umivrholidaygreetcontrol $ umivrweekendgreetcontrol $ umivrafterhoursgreetcontrol $ ummediaonholdsource ) )", "( 1.3.6.1.4.1.2415.3.35.2.1 NAME 'umuser' SUP top AUXILIARY MAY ( umpin $ umpinlastmodifytime $ umpwdlastmodifytime $ umprimaryfaxnumber $ umsecondaryfaxnumber $ umivrscheduledgreetingssettings $ umivroperatorschedulesettings $ umivrpersonaloperator $ umaccountlastaccesstime $ umivrgeneralmsgmailbox $ umivrcligreetingprefs $ umivrnonsubscribernameprefs $ umivraccesslastlocktime ) )", "( 1.3.6.1.4.1.2415.2.2.2.5 NAME 'mailuser' SUP top AUXILIARY MUST ( mail $ adminpolicydn ) MAY ( billingid $ mailalternateaddress $ mailautoreplyhost $ mailboxid $ mailboxstatus $ mailforwardingaddress $ maillogin $ mailmessagestore $ mailpassword $ mailpasswordtype $ mailpopproxyhost $ mailsmtprelayhost $ mailscoperestrictedaddress $ mailfrom $ mailreplyto $ mailsignature $ mailvcard $ mailrejectaction $ mailrejectinfo ) )", "( 1.3.6.1.4.1.2415.2.2.2.6 NAME 'mailuserprefs' SUP top AUXILIARY MAY ( mailforwarding $ mailparentalcontrol $ maildeliveryoption $ mailautoreplymode $ mailmtafilter $ mailmtafilterperuser $ mailsmtpauth $ mailsmtpaccess $ maildeliveryaccess $ mailsmtpsslaccess $ mailpopaccess $ mailpopsslaccess $ mailimapaccess $ mailimapsslaccess $ mailselfcare $ mailselfcaressl $ mailintermanager $ mailintermanagerssl $ mailquotabouncenotify $ mailquotatotkb $ mailquotamaxmsgkb $ mailquotamaxmsgs $ mailquotathreshold $ mailfolderquota $ mailbypassauthentication $ mailwebmailaccess $ mailwebmailsslaccess $ mailwebmailattachsizelimit $ mailwebmailmsgattachlimit $ mailwebmailattachlimit $ mailwebdisplay $ mailmobilemailaccess $ maildeliveryscope $ maildeniedsender $ maildeniedsenderaction $ maildeniedsendermessage $ mailwebmailaddressbooklimit $ mailwebmailaddressbooklistlimit $ mailwebmailusesignature $ mailwebmailconfirmdelete $ mailallowtheseips $ mailldapaccess $ mersenabled $ mersconfiguration $ mersfilebase $ mersfilesizekb $ mersmaxheaderlength $ mailrealm $ mailquotasendermaxmsgkb $ mailfuturedeliveryenabled $ mailfuturedeliveryquota $ mailfuturedeliverypending $ mailfuturedeliverymax $ mailimapproxyhost $ mailextensionsserviceattributes $ mailwebmaildeliveredtoaddress $ mailwebmaildeliveredtoaddresslist $ mailautosave $ mailautosignature $ mailautovcard $ mailincludeoriginal $ mailfamilymailbox $ mailwebmailexternalinboxserver $ mailbmimailwallspamactionverb $ mailbmimailwallvirusactionverb $ mailbmimailwallactioninfo $ mailpasswordhmac $ mailblocksendersaccess $ mailblocksendersactive $ mailapopaccess $ mailwebmailchangepassword $ mailpopunifyenabled $ mailpopunifyhost $ mailblocksenderspabaccess $ mailblocksenderspabactive $ mailsmtpenforcefrom $ mailindexhost $ mailsearchhost $ mailpopunifylogin $ mailpopunifypassword ) )", "( 1.3.6.1.4.1.2415.3.35.2.2 NAME 'umuserprefs' SUP top AUXILIARY MAY ( umpinpwdcheckexpiration $ umpinpwdcheckrules $ umenablevoicemail $ umenablefax $ umenablefaxautoprint $ umenableundeliverablenotification $ umenabledeliveryconfirmation $ umenablecheckreceipt $ umenableanonymousdelivery $ umenableprivatedelivery $ umenableurgentdelivery $ umenableundeletemsgs $ umsendvoicecontrol $ umvoiceoutdialcontrol $ umsendfaxcontrol $ umfaxoutdialcontrol $ umdestoutdialcontrol $ umivrenableasr $ ummaxphonenumbers $ ummaxfaxes $ ummaxfaxpages $ umvmmsdomain $ umivrenableautologin $ umivrenablevolumecontrol $ umivrenablespeedcontrol $ umivrenabletutorial $ umivrenablenamegreeting $ umivrenablepersonalgreeting $ umivrenablebusygreeting $ umivrenableskipusergreeting $ umivrenableskipcallergreeting $ umivrenableusertransfer $ umivrenablenestedvdls $ umivrcallertransfercontrol $ umivrautoplaycontrol $ umivrextendedabsencecontrol $ umivrmsgagingcontrol $ umivrplaybackorder $ umivrpersonaloperatordefault $ umivrmaxgreetingsecs $ umivrmaxmsgsecs $ umivrmaxcaptionsecs $ umivrmaxnewmsgdays $ umivrmaxsavedmsgdays $ umivrmaxvdls $ umivrmaxvdlentries $ umivrmaxvdlnamesecs $ umivrmaxnamesecs $ umivrtutorialentryname $ umivrskippin $ umivrautoprint $ umivrautoplay $ umivrplaytutorial $ umivrplaydatetime $ umivrpromptlevel $ umivrcallerlocales $ umivrflow $ umivrvariant $ umivrtimeentryformat $ umivrgeneralgreetings $ umenableemail $ umenableautoplayemail $ umwebenablereplyvoicefax $ umenablefuturedelivery $ umenablevideo $ umvmmspn $ umenableemptycallcapture $ ummessagedeliveryoptions $ umivrenablescheduledgreetings $ umivrcalleridrestricted $ umivrnumdigitsinextension $ umaddonservicelist $ umholidaylist $ umserviceslist $ umivrplaynameifavailable $ umivrfmfmmaxphonenumbers $ umivrfmfmphonenumber $ umdestsearchparam $ umivrenablephonelabels $ umfmballowduplicatepin $ umfmbchildattrlist $ umfmballowupdatebychild $ umivrenableavatarcontrol $ umivravatarprefs $ umivrmaxringbacktones $ umivrringbacktoneprefs $ umivrdefaultringbacktone $ umivravailringbacktones $ umivrmaxcelebgreetings $ umivrcelebgreetingprefs $ umivrdefaultcelebgreeting $ umivravailcelebgreetings $ umivrmaxcelebcligreetings $ umivrtriggerapps $ umivrtriggerappsdefault $ umivrmaxcligreetings $ umivrenablevdlcligreetings $ umivremaillangprefs $ umaggregatentfnprofile $ umntfnerroraction $ umntfnretrycriteria $ umpinmaxlength $ umpinminlength $ umpinpwdrules $ umpinpwdlifetimedays $ umservicecontrollist $ umivrenableplaycallbacknumber $ umivrplayonlymsghdrs $ umivrplayaniifavailable $ umivrenablecelebgreetings $ umivrenableringbacktones $ umivrallowadminaccess $ umivrenableadmincommercialtransfer $ umivrusertype $ umivrenablebbmailbox $ umenablecommercialgdluserprefs $ umenablebroadcast $ umivrenablebroadcastuserprefs $ umivrenablespeechtotext $ umenablespeechtotext $ umspeechtotextprioritysettings $ umivrenablelistenin $ umivrlistenintriggernumbers $ umivrenablelivereplyconf $ umivrconfmediaonhold $ umspeechtotexttranscriptionsettings $ umivrenableexchangetts $ umenableexchangetts $ umexchangeserveraddress $ umexchangeserverusername $ umexchangeserveruserpassword $ umivrenablereminderuserprefs $ umenablereminder $ umenablecontentsearch $ addressbookprovider $ umnabusername $ umnabpassword ) )"], "dITContentRules"=>[], "ldapSyntaxes"=>[], "attributeTypes"=> ["( 2.5.21.5 NAME 'attributetypes' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )", "( 2.5.21.6 NAME 'objectclasses' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )", "( 2.5.21.4 NAME 'matchingrules' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )", "( 2.5.21.8 NAME 'matchingruleuse' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )", "( 2.5.21.1 NAME 'ditstructurerules' EQUALITY integerFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 USAGE directoryOperation )", "( 2.5.21.7 NAME 'nameforms' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.35 USAGE directoryOperation )", "( 2.5.21.2 NAME 'ditcontentrules' EQUALITY objectIdentifierFirstComponentMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation )", "( 2.5.18.1 NAME 'createtimestamp' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 2.5.18.2 NAME 'modifytimestamp' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 2.5.18.3 NAME 'creatorsname' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 2.5.18.4 NAME 'modifiersname' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 2.5.18.10 NAME 'subschemasubentry' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingcontexts' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation )", "( 1.3.6.1.4.1.1466.101.120.6 NAME 'altserver' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation )", "( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedextension' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )", "( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedcontrol' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )", "( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedsaslmechanisms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )", "( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedldapversion' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} USAGE dSAOperation )", "( 2.5.4.0 NAME 'objectclass' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", "( 2.5.4.1 NAME 'aliasedobjectname' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", "( 2.5.4.2 NAME 'knowledgeinformation' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )", "( 2.5.4.3 NAME 'cn' SUP name )", "( 2.5.4.4 NAME 'sn' SUP name SINGLE-VALUE )", "( 2.5.4.5 NAME 'serialnumber' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} )", "( 2.5.4.6 NAME 'c' SUP name SINGLE-VALUE )", "( 2.5.4.7 NAME 'l' SUP name )", "( 2.5.4.8 NAME 'st' SUP name )", "( 2.5.4.9 NAME 'street' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )", "( 2.5.4.10 NAME 'o' SUP name )", "( 2.5.4.11 NAME 'ou' SUP name )", "( 2.5.4.12 NAME 'title' SUP name )", "( 2.5.4.13 NAME 'description' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )", "( 2.5.4.15 NAME 'businesscategory' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )", "( 2.5.4.16 NAME 'postaladdress' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", "( 2.5.4.17 NAME 'postalcode' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )", "( 2.5.4.18 NAME 'postofficebox' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{40} )", "( 2.5.4.19 NAME 'physicaldeliveryofficename' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )", "( 2.5.4.20 NAME 'telephonenumber' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )", "( 2.5.4.21 NAME 'telexnumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.52 )", "( 2.5.4.22 NAME 'teletexterminalidentifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.51 )", "( 2.5.4.23 NAME 'facsimiletelephonenumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 )", "( 2.5.4.24 NAME 'x121address' EQUALITY numericStringMatch ORDERING numericStringOrderingMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{15} )", "( 2.5.4.25 NAME 'internationalisdnnumber' EQUALITY numericStringMatch ORDERING numericStringOrderingMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{16} )", "( 2.5.4.26 NAME 'registeredaddress' SUP postalAddress SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", "( 2.5.4.27 NAME 'destinationindicator' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{128} )", "( 2.5.4.28 NAME 'preferreddeliverymethod' SYNTAX 1.3.6.1.4.1.1466.115.121.1.14 SINGLE-VALUE )", "( 2.5.4.29 NAME 'presentationaddress' EQUALITY presentationAddressMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 SINGLE-VALUE )", "( 2.5.4.30 NAME 'supportedapplicationcontext' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", "( 2.5.4.31 NAME 'member' SUP distinguishedName X-REFERENCES 'dn' )", "( 2.5.4.32 NAME 'owner' SUP distinguishedName )", "( 2.5.4.33 NAME 'roleoccupant' SUP distinguishedName )", "( 2.5.4.34 NAME 'seealso' SUP distinguishedName )", "( 2.5.4.35 NAME 'userpassword' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )", "( 2.5.4.36 NAME 'usercertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )", "( 2.5.4.37 NAME 'cacertificate' SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )", "( 2.5.4.38 NAME 'authorityrevocationlist' SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )", "( 2.5.4.39 NAME 'certificaterevocationlist' SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )", "( 2.5.4.40 NAME 'crosscertificatepair' SYNTAX 1.3.6.1.4.1.1466.115.121.1.10 )", "( 2.5.4.41 NAME 'name' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )", "( 2.5.4.42 NAME 'givenname' SUP name )", "( 2.5.4.43 NAME 'initials' SUP name )", "( 2.5.4.44 NAME 'generationqualifier' SUP name )", "( 2.5.4.45 NAME 'x500uniqueidentifier' EQUALITY bitStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", "( 2.5.4.46 NAME 'dnqualifier' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )", "( 2.5.4.47 NAME 'enhancedsearchguide' SYNTAX 1.3.6.1.4.1.1466.115.121.1.21 )", "( 2.5.4.48 NAME 'protocolinformation' EQUALITY protocolInformationMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )", "( 2.5.4.49 NAME 'distinguishedname' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", "( 2.5.4.50 NAME 'uniquemember' EQUALITY uniqueMemberMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", "( 2.5.4.51 NAME 'houseidentifier' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )", "( 2.5.4.52 NAME 'supportedalgorithms' SYNTAX 1.3.6.1.4.1.1466.115.121.1.49 )", "( 2.5.4.53 NAME 'deltarevocationlist' SYNTAX 1.3.6.1.4.1.1466.115.121.1.9 )", "( 2.5.4.54 NAME 'dmdname' SUP name )", "( 0.9.2342.19200300.100.1.25 NAME 'dc' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 2.16.840.1.113730.3.1.5 NAME 'changenumber' DESC 'a number which uniquely identifies a change made to a directory entry' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 2.16.840.1.113730.3.1.6 NAME 'targetdn' DESC 'the DN of the entry which was modified' EQUALITY distinguishedNameMatch SUBSTR distinguishedNameSubstringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", "( 2.16.840.1.113730.3.1.7 NAME 'changetype' DESC 'the type of change made to an entry' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.16.840.1.113730.3.1.8 NAME 'changes' DESC 'a set of changes to apply to an entry' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", "( 2.16.840.1.113730.3.1.9 NAME 'newrdn' DESC 'the new RDN of an entry which is the target of a modrdn operation' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", "( 2.16.840.1.113730.3.1.10 NAME 'deleteoldrdn' DESC 'a flag which indicates if the old RDN should be retained as an attribute of the entry' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )", "( 2.16.840.1.113730.3.1.11 NAME 'newsuperior' DESC 'the new parent of an entry which is the target of a moddn operation' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", "( 2.16.840.1.113730.3.1.35 NAME 'changelog' DESC 'the distinguished name of the entry which contains the set of entries comprising this server changelog' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", "( 2.16.840.1.113730.3.1.1 NAME 'carlicense' DESC 'vehicle license or registration plate' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.16.840.1.113730.3.1.2 NAME 'departmentnumber' DESC 'identifies a department within an organization' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.16.840.1.113730.3.1.241 NAME 'displayname' DESC 'preferred name of a person to be used when displaying entries' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.16.840.1.113730.3.1.3 NAME 'employeenumber' DESC 'numerically identifies an employee within an organization' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 2.16.840.1.113730.3.1.4 NAME 'employeetype' DESC 'type of employment for a person' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 0.9.2342.19200300.100.1.60 NAME 'jpegphoto' DESC 'a JPEG image' SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 )", "( 2.16.840.1.113730.3.1.39 NAME 'preferredlanguage' DESC 'preferred written or spoken language for a person' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 2.16.840.1.113730.3.1.40 NAME 'usersmimecertificate' DESC 'signed message used to support S/MIME' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", "( 2.16.840.1.113730.3.1.216 NAME 'userpkcs12' DESC 'PKCS #12 PFX PDU for exchange of personal identity information' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", "( 0.9.2342.19200300.100.1.55 NAME 'audio' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{250000} )", "( 0.9.2342.19200300.100.1.20 NAME 'homephone' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", "( 0.9.2342.19200300.100.1.39 NAME 'homepostaladdress' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", "( 0.9.2342.19200300.100.1.3 NAME 'mail' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 0.9.2342.19200300.100.1.10 NAME 'manager' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", "( 0.9.2342.19200300.100.1.41 NAME 'mobile' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", "( 0.9.2342.19200300.100.1.42 NAME 'pager' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", "( 0.9.2342.19200300.100.1.6 NAME 'roomnumber' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )", "( 0.9.2342.19200300.100.1.21 NAME 'secretary' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", "( 0.9.2342.19200300.100.1.7 NAME 'photo' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", "( 0.9.2342.19200300.100.1.1 NAME 'uid' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )", "( 1.3.6.1.4.1.250.1.57 NAME 'labeleduri' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.16.840.1.113730.3.1.16 NAME 'maildeliveryoption' DESC 'Standard Attribute' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,P,N,E,S' )", "( 2.16.840.1.113730.3.1.14 NAME 'mailautoreplymode' DESC 'Standard Attribute' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,N,R,E,V' )", "( 2.16.840.1.113730.3.1.17 NAME 'mailforwardingaddress' DESC 'Standard Attribute' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )", "( 2.16.840.1.113730.3.1.13 NAME 'mailalternateaddress' DESC 'alternate RFC 822 email address of this recipient' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )", "( 2.16.840.1.113730.3.1.34 NAME 'ref' DESC 'URL reference' EQUALITY caseExactIA5Match ORDERING caseExactIA5OrderingMatch SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.1 NAME 'adminpolicydn' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-REFERENCES '(objectclass=adminpolicy).dn' )", "( 1.3.6.1.4.1.2415.2.2.1.2 NAME 'adminmaxusers' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.3 NAME 'adminnumusers' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.4 NAME 'domainname' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.5 NAME 'domaintype' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,L,R,N,I' )", "( 1.3.6.1.4.1.2415.2.2.1.6 NAME 'mailrelayhost' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{97} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.7 NAME 'mailrewritedomain' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.8 NAME 'mailwildcardaccount' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.9 NAME 'scschemafiletimestamp' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.10 NAME 'mailpopproxyhost' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.11 NAME 'mailsmtprelayhost' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.12 NAME 'mailautoreplyhost' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.13 NAME ( 'mailpassword' 'msgpassword' ) EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.14 NAME ( 'mailpasswordtype' 'msgpasswordtype' ) EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,C,M,U,S,H,1,2,3,4,5' )", "( 1.3.6.1.4.1.2415.2.2.1.15 NAME 'mailintermanagerssl' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.16 NAME 'mailimapsslaccess' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,trusted,none' )", "( 1.3.6.1.4.1.2415.2.2.1.17 NAME ( 'mailboxstatus' 'msguserstatus' ) EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,A,D,S,L,M,P' )", "( 1.3.6.1.4.1.2415.2.2.1.19 NAME ( 'maillogin' 'msgusername' ) EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{129} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.20 NAME ( 'mailboxid' 'msguserid' ) EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.21 NAME 'billingid' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.22 NAME 'updateinterval' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.2.1.23 NAME 'contactinfo' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.24 NAME 'mailpopaccess' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,trusted,none' )", "( 1.3.6.1.4.1.2415.2.2.1.25 NAME 'mailsmtpaccess' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.26 NAME 'mailimapaccess' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,trusted,none' )", "( 1.3.6.1.4.1.2415.2.2.1.27 NAME 'mailpopsslaccess' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,trusted,none' )", "( 1.3.6.1.4.1.2415.2.2.1.28 NAME 'mailsmtpsslaccess' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.29 NAME 'mailsmtpauth' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.30 NAME 'mailmtafilter' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.31 NAME 'mailquotabouncenotify' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.32 NAME 'mailforwarding' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.33 NAME 'replarea' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.34 NAME 'mailselfcare' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.35 NAME 'mailselfcaressl' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.36 NAME 'mailintermanager' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.39 NAME 'mailquotamaxmsgs' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.2.1.40 NAME 'mailquotathreshold' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-100' )", "( 1.3.6.1.4.1.2415.2.2.1.41 NAME 'mailbypassauthentication' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.42 NAME 'mailwebmailaccess' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,trusted,none' )", "( 1.3.6.1.4.1.2415.2.2.1.43 NAME 'mailwebmailattachsizelimit' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.2.1.44 NAME 'mailwebmailmsgattachlimit' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.2.1.45 NAME 'mailwebmailattachlimit' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.2.1.46 NAME 'mailwebmailaddressbooklimit' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.2.1.47 NAME 'mailwebmailaddressbooklistlimit' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.2.1.48 NAME 'mailwebmailusesignature' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.49 NAME 'mailwebmailconfirmdelete' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.50 NAME 'mailwebdisplay' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.51 NAME 'mailmtafilterperuser' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.52 NAME 'supplierreference' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.53 NAME 'consumeridentity' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.54 NAME 'consumerpassword' EQUALITY octetStringMatch ORDERING octetStringOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} SINGLE-VALUE USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.56 NAME 'lastchangenumber' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE NO-USER-MODIFICATION USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.57 NAME 'adminpolicydefaultdn' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-REFERENCES 'dn' )", "( 1.3.6.1.4.1.2415.2.2.1.58 NAME 'firstchangenumber' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE NO-USER-MODIFICATION USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.59 NAME 'partition' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.60 NAME 'partitionname' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.61 NAME 'mailmessagestore' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.62 NAME 'adminapprovedsenderslist' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.63 NAME 'acirule' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.1 USAGE dSAOperation )", "( 1.3.6.1.4.1.2415.2.2.1.64 NAME 'mailparentalcontrol' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.65 NAME 'targetpartitionname' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.66 NAME 'adminpolicygrantdn' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES 'dn' )", "( 1.3.6.1.4.1.2415.2.2.1.67 NAME 'adminmaxrealms' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.68 NAME 'adminsuperiorattributeconstraint' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.69 NAME 'adminparentalrejectaction' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,drop,forward' )", "( 1.3.6.1.4.1.2415.2.2.1.70 NAME 'admintargetdn' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES '(objectclass=adminTarget).dn' )", "( 1.3.6.1.4.1.2415.2.2.1.71 NAME 'adminmaxstoragekb' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.72 NAME 'adminusedstoragekb' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.73 NAME 'adminmaxsmtpssl' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.74 NAME 'adminnumsmtpssl' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.75 NAME 'adminmaxpop' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.76 NAME 'adminnumpop' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.77 NAME 'adminmaxpopssl' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.78 NAME 'adminnumpopssl' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.79 NAME 'adminmaximap' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.80 NAME 'adminnumimap' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.81 NAME 'adminmaximapssl' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.82 NAME 'adminnumimapssl' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.83 NAME 'adminmaxwebmail' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.84 NAME 'adminnumwebmail' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.85 NAME 'adminmaxselfcare' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.86 NAME 'adminnumselfcare' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.87 NAME 'adminmaxintermanager' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.88 NAME 'adminnumintermanager' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.90 NAME 'adminmaxmailinglists' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.91 NAME 'adminnummailinglists' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.92 NAME 'adminaccesslevel' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.93 NAME 'admincreaterealm' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.94 NAME 'admindeleterealm' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.95 NAME 'admincreatepeeradmingroup' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES 'dn' )", "( 1.3.6.1.4.1.2415.2.2.1.96 NAME 'admindeletepeeradmingroup' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES 'dn' )", "( 1.3.6.1.4.1.2415.2.2.1.97 NAME 'adminnumrealms' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.98 NAME 'admincreatesubadmingroup' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES 'dn' )", "( 1.3.6.1.4.1.2415.2.2.1.99 NAME 'admindeletesubadmingroup' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES 'dn' )", "( 1.3.6.1.4.1.2415.2.2.1.100 NAME 'adminmaxsmtp' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.101 NAME 'admincreatepeeradminpolicy' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.102 NAME 'admindeletepeeradminpolicy' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.103 NAME 'admincreatesubadminpolicy' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.104 NAME 'admindeletesubadminpolicy' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.105 NAME 'adminmaxmaildomains' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.106 NAME 'adminnummaildomains' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.107 NAME 'adminallowedcreateclasses' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.108 NAME 'adminallowedupdateclasses' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.109 NAME 'adminroledn' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-REFERENCES '(objectclass=adminRole).dn' )", "( 1.3.6.1.4.1.2415.2.2.1.110 NAME 'adminalloweddomains' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.2.1.111 NAME 'adminallowedadminpolicydn' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES '(objectclass=adminPolicy).dn' )", "( 1.3.6.1.4.1.2415.2.2.1.112 NAME 'adminparentdomains' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.2.1.113 NAME 'adminrealmdn' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-REFERENCES '(objectclass=adminRealm).dn' )", "( 1.3.6.1.4.1.2415.2.2.1.114 NAME 'adminattributeconstraint' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.115 NAME 'adminprovisiononly' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.116 NAME 'admintemplateonly' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.117 NAME 'mailallowtheseips' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{64} )", "( 1.3.6.1.4.1.2415.2.2.1.118 NAME 'mailldapaccess' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,trusted,none' )", "( 1.3.6.1.4.1.2415.2.2.1.119 NAME 'listlocalsubscriptionoption' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,open,closed,closednotify,moderated' )", "( 1.3.6.1.4.1.2415.2.2.1.120 NAME 'listremotesubscriptionoption' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,open,closed,closednotify,moderated' )", "( 1.3.6.1.4.1.2415.2.2.1.121 NAME 'listsubscriptionmoderationmethod' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,web,email,both' )", "( 1.3.6.1.4.1.2415.2.2.1.122 NAME 'listverifysubscriberequest' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.123 NAME 'listunsubscriptionoption' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,open,closed,closednotify,moderated' )", "( 1.3.6.1.4.1.2415.2.2.1.124 NAME 'listunsubscriptionmoderationmethod' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,web,email,both' )", "( 1.3.6.1.4.1.2415.2.2.1.125 NAME 'listverifyunsubscriberequest' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.126 NAME 'listaccesssubscriberlistoption' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )", "( 1.3.6.1.4.1.2415.2.2.1.127 NAME 'listsubscriberpostingoption' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,open,closed,closednotify,moderated' )", "( 1.3.6.1.4.1.2415.2.2.1.128 NAME 'listnonsubscriberpostingoption' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,open,closed,closednotify,moderated' )", "( 1.3.6.1.4.1.2415.2.2.1.129 NAME 'listpostingmoderationmethod' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,web,email,both' )", "( 1.3.6.1.4.1.2415.2.2.1.130 NAME 'listdetectrequest' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.131 NAME 'listdeliverymode' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,immediate,digest,both' )", "( 1.3.6.1.4.1.2415.2.2.1.132 NAME 'listaddressexpansionstyle' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,none,group,expand' )", "( 1.3.6.1.4.1.2415.2.2.1.133 NAME 'listquotamaxsubscribers' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.134 NAME 'listquotamaxmsgsizekb' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.135 NAME 'listquotamaxmsgsperday' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.136 NAME 'listquotamaxvolumekbperday' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.137 NAME 'listextendedlocaldomains' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )", "( 1.3.6.1.4.1.2415.2.2.1.138 NAME 'listwelcomemessage' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.139 NAME 'listgoodbyemessage' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.140 NAME 'listprologuetext' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.141 NAME 'listepiloguetext' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.142 NAME 'listheaderstobeadded' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.2.1.144 NAME 'listheaderstorewrite' EQUALITY caseExactIA5Match ORDERING caseExactIA5OrderingMatch SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.2.1.145 NAME 'listremovexheaders' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.146 NAME 'listapprovedposters' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.2.1.147 NAME 'listdigestvolumenumber' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.148 NAME 'listdigestissuenumber' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.149 NAME 'listdigestdeliverytime' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )", "( 1.3.6.1.4.1.2415.2.2.1.150 NAME 'liststatsdeliverytime' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )", "( 1.3.6.1.4.1.2415.2.2.1.151 NAME 'listmaxbouncespersubscriber' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.152 NAME 'liststatsmessages' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.153 NAME 'liststatsvolume' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.154 NAME 'liststatsnewsubscribers' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.155 NAME 'liststatsunsubscribers' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.156 NAME 'liststatsforcedunsubscribers' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.157 NAME 'liststatsmessageswaiting' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.158 NAME 'liststatssubscriberswaiting' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.159 NAME 'liststatsunsubscriberswaiting' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.160 NAME 'liststatisticsnotification' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.161 NAME 'listbouncenotification' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.162 NAME 'listoverlimitnotification' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.163 NAME 'listdynamic' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.164 NAME 'listdynamicbase' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.165 NAME 'listsubscriberaddress' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )", "( 1.3.6.1.4.1.2415.2.2.1.166 NAME 'liststatsbounces' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.167 NAME 'adminpreferredlocale' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.168 NAME 'adminlastlogin' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.169 NAME 'sccachedirdbstatus' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.171 NAME 'adminparentadminpolicy' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-REFERENCES '(objectclass=adminPolicy).dn' )", "( 1.3.6.1.4.1.2415.2.2.1.172 NAME 'adminnumsmtp' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.173 NAME 'adminmaxdomains' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.174 NAME 'adminnumdomains' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.70 NAME 'adminmaxorgs' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.60.1.71 NAME 'adminnumorgs' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.72 NAME 'adminmaxorgunits' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.60.1.73 NAME 'adminnumorgunits' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.175 NAME 'adminallocrules' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.2.1.176 NAME 'adminallocsubtots' SUP name )", "( 1.3.6.1.4.1.2415.2.2.1.177 NAME 'adminrealmtype' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,provider,org,ou,family,group' )", "( 1.3.6.1.4.1.2415.2.2.1.178 NAME 'admindefaultcreatedgroups' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES 'dn' )", "( 1.3.6.1.4.1.2415.2.2.1.179 NAME 'admintargetobjectclass' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )", "( 1.3.6.1.4.1.2415.2.2.1.180 NAME 'admindomainspeccontrol' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.181 NAME 'adminminallowedaccesslevel' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.182 NAME 'adminpolicydnused' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-REFERENCES '(objectclass=adminPolicy).dn' )", "( 1.3.6.1.4.1.2415.2.2.1.184 NAME 'lastexpirednumber' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.185 NAME 'targetentryid' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.186 NAME 'entryid' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.187 NAME 'objecttype' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.188 NAME 'firstentryid' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.189 NAME 'lastentryid' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.190 NAME 'mersfilesizekb' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.191 NAME 'mersmaxheaderlength' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.192 NAME 'mersmssinstances' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.193 NAME 'mersenabled' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.194 NAME 'mersconfiguration' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.195 NAME 'mersfilebase' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.196 NAME 'changeid' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.197 NAME 'listlastdigestdelivery' EQUALITY numericStringMatch ORDERING numericStringOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{14} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.198 NAME 'listlaststatsdelivery' EQUALITY numericStringMatch ORDERING numericStringOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{14} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.199 NAME 'listsuppressnotifications' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.200 NAME 'targetdomainname' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.201 NAME 'swcmrebuildentrydata' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.202 NAME 'maildeliveryscope' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,global,local' )", "( 1.3.6.1.4.1.2415.2.2.1.203 NAME 'maildeniedsender' DESC 'Senders from which a recipient will not accept mail.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )", "( 1.3.6.1.4.1.2415.2.2.1.204 NAME 'maildeniedsenderaction' DESC 'The action taken when the account rejects mail from a sender.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,bounce,reject,sideline,toss,none' )", "( 1.3.6.1.4.1.2415.2.2.1.205 NAME 'maildeniedsendermessage' DESC 'A message associated with the mailDeniedSenderAction.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.207 NAME 'dn' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.208 NAME 'parentid' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.2.1.209 NAME 'clusterindex' DESC 'Cluster object attribute used to store cluster index information.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.210 NAME 'clusterentryfilter' DESC 'Cluster object attribute used to store entry filter information.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.211 NAME 'clusterrouters' DESC 'Cluster object attribute used to store list of router hosts.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.212 NAME 'clusterentryservers' DESC 'Cluster object attribute used to store entry server hosts for a router' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.213 NAME 'clusterindexservers' DESC 'Cluster object attribute used to store index server hosts for a router' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.214 NAME 'targetnewpartitionname' DESC 'This attribute can appear in changelog entries.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.215 NAME 'oldpartitionname' DESC 'This is a dummy attribute.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.216 NAME 'newpartitionname' DESC 'This is a dummy attribute.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.217 NAME 'entry' DESC 'complete entry in the changelog' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", "( 1.3.6.1.4.1.2415.2.2.1.218 NAME 'mailrealm' DESC 'The realm associated with an account.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.219 NAME 'lastupdatedtime' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.220 NAME 'nextupdatetime' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.221 NAME 'lastlcnchgtime' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION USAGE distributedOperation )", "( 1.3.6.1.4.1.2415.2.2.1.222 NAME 'maildeliveryaccess' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.2.1.223 NAME 'mailimapproxyhost' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.224 NAME 'mailwebmailexternalinboxserver' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.225 NAME 'adminmaxwebmailssl' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.226 NAME 'adminnumwebmailssl' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.227 NAME 'mailmobilemailaccess' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,trusted,none' )", "( 1.3.6.1.4.1.2415.2.2.1.228 NAME 'adminmaxmobilemail' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-9223372036854775807' )", "( 1.3.6.1.4.1.2415.2.2.1.229 NAME 'adminnummobilemail' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.230 NAME 'mailpasswordhmac' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.923.2.1.15 NAME 'mailwebmailsslaccess' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,trusted,none' )", "( 1.3.6.1.4.1.2415.2.2.1.301 NAME 'mailbmimailwallspamactionverb' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.302 NAME 'mailbmimailwallvirusactionverb' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.303 NAME 'mailbmimailwallactioninfo' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.306 NAME 'adminallowedmessagestorehosts' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.2.1.307 NAME 'adminallowedautoreplyhosts' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.2.1.308 NAME 'relateddn' DESC 'additional DNs this change log is related to' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.60.1.1 NAME 'mailfuturedeliveryenabled' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.60.1.2 NAME 'mailfuturedeliveryquota' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.60.1.3 NAME 'mailfuturedeliverypending' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )", "( 1.3.6.1.4.1.2415.2.60.1.4 NAME 'mailfuturedeliverymax' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.2.60.1.5 NAME 'listdynamicfilter' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.60.1.7 NAME 'mailscoperestrictedaddress' DESC 'RFC 822 address identifying accounts restricted to local delivery' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )", "( 1.1.3.6.1.4.1.2415.2.60.1.51 NAME 'mailextensionsserviceattributes' DESC 'Defines the configuration for an extension service.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.60.1.6 NAME 'attrid' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} NO-USER-MODIFICATION )", "( 1.3.6.1.4.1.2415.2.52.1.2 NAME 'entrysize' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.52.1.3 NAME 'mailwebmaildeliveredtoaddress' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.52.1.4 NAME 'mailwebmaildeliveredtoaddresslist' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.52 NAME 'msgsecretquestion' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.53 NAME 'msgsecretanswer' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.54 NAME 'msglocale' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.55 NAME 'msgcharset' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.56 NAME 'msgtimezone' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.57 NAME 'mailfrom' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.58 NAME 'mailreplyto' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.59 NAME 'mailsignature' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.60 NAME 'mailvcard' EQUALITY caseIgnoreListMatch SUBSTR caseIgnoreListSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.61 NAME 'mailautosave' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.60.1.62 NAME 'mailautosignature' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.60.1.63 NAME 'mailautovcard' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.60.1.64 NAME 'mailincludeoriginal' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.60.1.65 NAME 'mailfamilymailbox' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2' )", "( 1.3.6.1.4.1.2415.2.52.1.7 NAME 'mailapopaccess' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2' )", "( 0.9.2342.19200300.100.1.40 NAME 'personaltitle' DESC 'contains values like Mr., Mrs., Miss, Dr. etc.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )", "( 1.3.6.1.4.1.2415.2.3.1.1 NAME 'nickname' SUP name )", "( 1.3.6.1.4.1.2415.2.3.1.2 NAME 'middlename' SUP name )", "( 1.3.6.1.4.1.2415.2.3.1.3 NAME 'otherphonenumber' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", "( 1.3.6.1.4.1.2415.2.3.1.4 NAME 'birthday' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.3.1.5 NAME 'anniversary' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.3.1.6 NAME 'notes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.3.1.7 NAME 'mailsecondaryaddress' DESC 'alternate RFC 822 email address' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )", "( 1.3.6.1.4.1.2415.2.3.1.8 NAME 'homefacsimiletelephonenumber' SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 )", "( 1.3.6.1.4.1.2415.2.3.1.9 NAME 'homemobile' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", "( 1.3.6.1.4.1.2415.2.3.1.10 NAME 'homepager' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", "( 1.3.6.1.4.1.2415.2.3.1.11 NAME 'homelink' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.3.1.12 NAME 'worklink' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.3.1.13 NAME 'spousename' SUP name )", "( 1.3.6.1.4.1.2415.2.3.1.14 NAME 'gender' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.3.1.15 NAME 'childname' SUP name )", "( 1.3.6.1.4.1.2415.2.3.1.16 NAME 'addressbookdn' SUP distinguishedName )", "( 1.3.6.1.4.1.2415.2.3.1.17 NAME 'mailprimaryaddress' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.3.1.18 NAME 'corpmailprimaryaddress' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.67 NAME 'corpaddressbookallowed' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,true,blocked,false' )", "( 1.3.6.1.4.1.2415.2.60.1.68 NAME 'corpaddressbookwanted' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,true,false' )", "( 1.3.6.1.4.1.2415.7.55.1.1 NAME 'adminblockedsenderslist' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.7.55.1.2 NAME 'adminparentalrejectinfo' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.7.55.1.3 NAME 'adminparentaldefaultdisposition' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,accept,reject' )", "( 1.3.6.1.4.1.2415.7.55.1.4 NAME 'mailblocksendersaccess' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.7.55.1.5 NAME 'mailblocksendersactive' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27{38} SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.7.55.1.6 NAME 'mailapprovedsenderslist' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.7.55.1.7 NAME 'mailblockedsenderslist' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.7.55.1.8 NAME 'mailrejectaction' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,drop,forward' )", "( 1.3.6.1.4.1.2415.7.55.1.9 NAME 'mailrejectinfo' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.7.55.1.10 NAME 'adminbmimailwallspamactionverb' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.1 NAME 'umpin' DESC 'User PIN' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.2 NAME 'umpinlastmodifytime' DESC 'Timestamp of latest PIN change' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.3 NAME 'umpwdlastmodifytime' DESC 'Timestamp of latest password change' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.4 NAME 'umprimaryfaxnumber' DESC 'Primary fax number to print to' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.5 NAME 'umvmmspn' DESC 'Voice MMS phone number in canonical form cc.rc.line[-ext]' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.6 NAME 'umivrpersonaloperator' DESC 'Phone number for personal assistant-operator' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.7 NAME 'umaccountlastaccesstime' DESC 'Last account access timestamp' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.8 NAME 'umivrgeneralmsgmailbox' DESC 'General message mailbox (default)' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.101 NAME 'umpinpwdcheckexpiration' DESC 'Whether to check pin/password expiration' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.102 NAME 'umpinpwdcheckrules' DESC 'Whether to check new pin/password rules violation' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.103 NAME 'umfmballowduplicatepin' DESC 'Allow duplicate password for sub mailboxes' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.131 NAME 'umenablevoicemail' DESC 'Voicemail features' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.132 NAME 'umenablefax' DESC 'Fax features' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.133 NAME 'umenablefaxautoprint' DESC 'Allow auto-forwarding faxes to umPrimaryFaxNumber' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.134 NAME 'umenableundeliverablenotification' DESC 'Allow notification of undeliverable messages' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.135 NAME 'umenabledeliveryconfirmation' DESC 'Allow delivery confirmation' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.136 NAME 'umenablecheckreceipt' DESC 'Allow checking message delivery to another subscriber' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.137 NAME 'umenableanonymousdelivery' DESC 'Allow marking messages anonymous' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.138 NAME 'umenableprivatedelivery' DESC 'Allow marking messages private' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.139 NAME 'umenableurgentdelivery' DESC 'Allow marking messages urgent' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.140 NAME 'umenableundeletemsgs' DESC 'Allow undelete messages' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.141 NAME 'umenableemail' DESC 'Allow listening to email messages' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.142 NAME 'umenableautoplayemail' DESC 'Allow automatic playing of email message body after envelope is played' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.143 NAME 'umenableemptycallcapture' DESC 'Enable the empty call capture feature so that subscriber can receive an empty message without body.' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.144 NAME 'umwebenablereplyvoicefax' DESC 'Enable replying to voice and fax messages from web' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.145 NAME 'umenablefuturedelivery' DESC 'Enable sending future delivery messages for (this is required in addition to mailfuturedeliveryenabled attribute)' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.146 NAME 'umenablevideo' DESC 'Video features' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.147 NAME 'umfmbchildattrlist' DESC 'List of attributes to be inherited from HOH to sub mailboxes' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.148 NAME 'umfmballowupdatebychild' DESC 'Allow interited attributes to be updated in sub mailboxes' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.149 NAME 'umivrenableavatarcontrol' DESC 'Allow system avatar control' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.150 NAME 'umivravatarprefs' DESC 'System avatar preference' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.151 NAME 'umivremaillangprefs' DESC 'Email language preference' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.161 NAME 'umsendvoicecontrol' DESC 'Voice message delivery control: A-all, F-family, S-system, 0-disabled' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,F,D,S,A' )", "( 1.3.6.1.4.1.2415.3.35.1.162 NAME 'umvoiceoutdialcontrol' DESC 'Voice outdial control: L-Local only, R-interRegion, I-International, 0-disabled' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,L,R,I' )", "( 1.3.6.1.4.1.2415.3.35.1.163 NAME 'umsendfaxcontrol' DESC 'Fax message delivery control: A-all, F-family, S-system, 0-disabled' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,F,S,A' )", "( 1.3.6.1.4.1.2415.3.35.1.164 NAME 'umfaxoutdialcontrol' DESC 'Fax outdial control: L-Local only, R-interRegion, I-International, 0-disabled' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,L,R,I' )", "( 1.3.6.1.4.1.2415.3.35.1.165 NAME 'ummessagedeliveryoptions' DESC 'Message delivery options: V-Voice Mail, M-Voice MMS, B-Both Voice Mail and Voice MMS' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,V,M,B' )", "( 1.3.6.1.4.1.2415.3.35.1.181 NAME 'ummaxphonenumbers' DESC 'Max number of account phone numbers including primary number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.182 NAME 'ummaxfaxes' DESC 'Max number of fax messages' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.183 NAME 'ummaxfaxpages' DESC 'Max number of pages per fax message' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.191 NAME 'umvmmsdomain' DESC 'Domain name for Voice MMS message delivery' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.201 NAME 'umivrenableautologin' DESC 'Allow autologin' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.202 NAME 'umivrenablevolumecontrol' DESC 'Allow volume control' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.203 NAME 'umivrenablespeedcontrol' DESC 'Allow speed control' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.204 NAME 'umivrenabletutorial' DESC 'Allow play tutorial' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.205 NAME 'umivrenablenamegreeting' DESC 'Allow recorded name greeting' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.206 NAME 'umivrenablepersonalgreeting' DESC 'Allow recorded personal greeting' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.207 NAME 'umivrenablebusygreeting' DESC 'Allow recorded greeting to replace busy tone' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.208 NAME 'umivrenableskipusergreeting' DESC 'Allow skipping greeting and go directly to PIN prompt' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.209 NAME 'umivrenableskipcallergreeting' DESC 'Allow skipping greeting and go directly to recording prompt' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.210 NAME 'umivrenableusertransfer' DESC 'Allow transfering subscriber to operator' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.211 NAME 'umivrenablenestedvdls' DESC 'Allow nested voice distribution lists' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.212 NAME 'umivrenablescheduledgreetings' DESC 'Allow scheduled greetings' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.213 NAME 'umivrscheduledgreetingssettings' DESC 'Scheduled greetings settings' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.214 NAME 'umivrcalleridrestricted' DESC 'Whether messages are sent as anonymous: 0-disabled, 1-enabled' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.215 NAME 'umivroperatorschedulesettings' DESC 'A multi value attribute used in operator schedules' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.216 NAME 'umivrmaxcligreetings' DESC 'Max number of CLI greetings' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.217 NAME 'umivrcligreetingprefs' DESC 'CLI greeting preferences' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.231 NAME 'umivrcallertransfercontrol' DESC 'Inbound caller transfer to operator control: 0-disabled, T-transfer enabled, S-supervised transfer' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,S,T' )", "( 1.3.6.1.4.1.2415.3.35.1.232 NAME 'umivrautoplaycontrol' DESC 'What to do with messages after autoplay: 0-disabled, N-play and keep new, S-play and save' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,N,S' )", "( 1.3.6.1.4.1.2415.3.35.1.233 NAME 'umivrextendedabsencecontrol' DESC 'Extended absence greeting flow control: 0-Disabled, C-Disconnect, M-Allow Msg, T- Allow Transfer' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,C,M,T' )", "( 1.3.6.1.4.1.2415.3.35.1.234 NAME 'umivrmsgagingcontrol' DESC 'Options to aged messages: 0-disabled, S-resave after review, R-delete after review, W-delete with warning, D-delete' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,S,R,W,D' )", "( 1.3.6.1.4.1.2415.3.35.1.235 NAME 'umivrplaybackorder' DESC 'Playback order: D-default, F-FIFO, L-LIFO' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,D,F,L' )", "( 1.3.6.1.4.1.2415.3.35.1.236 NAME 'umivrpersonaloperatordefault' DESC 'How to select default value for personal operator: O-operator, P-user setting' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,O,P' )", "( 1.3.6.1.4.1.2415.3.35.1.251 NAME 'umivrmaxgreetingsecs' DESC 'Personal greeting max length in secs' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.252 NAME 'umivrmaxmsgsecs' DESC 'Single message max length in secs' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.253 NAME 'umivrmaxnewmsgdays' DESC 'Max number of days a new message can be stored' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.254 NAME 'umivrmaxsavedmsgdays' DESC 'Max number of days a saved message can be stored' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.255 NAME 'umivrmaxvdls' DESC 'Max number of voice distribution lists' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.256 NAME 'umivrmaxvdlentries' DESC 'Max number of entries in each voice distribution list' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.257 NAME 'umivrmaxvdlnamesecs' DESC 'Max duration of message for voice distribution list' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.258 NAME 'umivrmaxnamesecs' DESC 'Recorded name max length in secs' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.259 NAME 'umivrnumdigitsinextension' DESC 'Number of digits in extension' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.281 NAME 'umivrtutorialentryname' DESC 'Tutorial entry page name' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.301 NAME 'umivrskippin' DESC 'Skip pin at login; umIvrEnableAutoLogin has be to on' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.303 NAME 'umivrautoplay' DESC 'Allow bypassing all prompts and directly playing messages' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.304 NAME 'umivrplaytutorial' DESC 'Allow play tutorial at next login' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.305 NAME 'umivrplaydatetime' DESC 'Allow announcement of message timestamps' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.306 NAME 'umivrpromptlevel' DESC 'Menu prompt setting: S-standard, R-rapid, E-extended' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,S,R,E' )", "( 1.3.6.1.4.1.2415.3.35.1.307 NAME 'umivrcallerlocales' DESC 'List of languages picked by user for answering callers' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.308 NAME 'umivrflow' DESC 'Call flow name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.309 NAME 'umivrgeneralgreetings' DESC 'Greetings configuration shared by all phones' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.310 NAME 'umivrvariant' DESC 'Variant name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.311 NAME 'umivrtimeentryformat' DESC 'Time format used to exchange date/time information with the user, recognized formats are HHMM24, HHMM12' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.313 NAME 'umholidaylist' DESC 'List of holidays with format YYYY;MMDD,MMDD,MMDD...' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.314 NAME 'umserviceslist' DESC 'List of messaging services with format service-name;key=value,key=value' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.315 NAME 'umivrplaynameifavailable' DESC 'Allow announcement of sender name if it is recorded' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.316 NAME 'umivrfmfmmaxphonenumbers' DESC 'Max number of phone numbers used in find me follow me' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.317 NAME 'umivrfmfmphonenumber' DESC 'List of phone number in find me follow me in the format ;order=;...' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.401 NAME 'umpn' DESC 'Phone number in canonical form cc.rc.line[-ext]' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.402 NAME 'umpntype' DESC 'Phone number type: M-mailbox, D-DTMF target, S-Special mailbox, E-Extension, F-forward target, K-pickup target, O-operator target, P-prompt target, W-wireless target' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,M,D,S,E,F,K,O,P,W' )", "( 1.3.6.1.4.1.2415.3.35.1.404 NAME 'umpnlabel' DESC 'Phone number related extra info for internal use' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.405 NAME 'umpngreetings' DESC 'Per phone greetings configuration for internal use' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.502 NAME 'umivrenablebusyrnaoption' DESC 'Allow busy or ring-no-answer options: 0-disabled, 1-enabled' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.503 NAME 'umivrenablecallermenu' DESC 'Allow caller menu: 0-disabled, 1-enabled' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.504 NAME 'umivrnumringsbeforetransfer' DESC 'Number of rings before a call is transfered' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,1-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.505 NAME 'umivrpoundkeycontrol' DESC 'Pound key behavior: S-subscriber access, A-Administrator access, I-Ignore' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,S,A,I' )", "( 1.3.6.1.4.1.2415.3.35.1.506 NAME 'umivrstarkeycontrol' DESC 'Star key behavior: E-exit, I-ignore, M-mailbox, D-dial another phone number' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,E,I,M,D' )", "( 1.3.6.1.4.1.2415.3.35.1.507 NAME 'umivrstarkeymailbox' DESC 'Phone number for a mailbox accessed on start key input' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.508 NAME 'umivrecpmaxnoinput' DESC 'Max number of input attempts before a call is transfered to the operator' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.509 NAME 'umivrecpmaxnomatch' DESC 'Max number of invalid key entries allowed before a call is transfered to the operator' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.510 NAME 'umivrecpcallermenu' DESC 'Caller menu for internal use' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.511 NAME 'umivrcallforwardingmethod' DESC 'Call forwarding method for a special mailbox: T-transfer the call to specified destination, M-forward call directly to mailbox' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,T,M' )", "( 1.3.6.1.4.1.2415.3.35.1.512 NAME 'umivrextensiontype' DESC 'Mailbox extension type: D-DID, E-Extension' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,D,E' )", "( 1.3.6.1.4.1.2415.3.35.1.513 NAME 'umivrphoneextensionprefix' DESC 'Leading part of the phone number' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.514 NAME 'umivrspecialmailboxtype' DESC 'Special mailbox type in verbose form (e.g. ECP, TRANSFER, INFO)' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.602 NAME 'umivrenablephonelabels' DESC 'Allow labelling of phone numbers for multi-number account' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.700 NAME 'umdbnmaxnamestoprompt' DESC 'Maximum number of names to be prompted for Dial-By-Name' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,1-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.701 NAME 'umdbnmindigitstoenter' DESC 'Minimum number of digits required for Dial-By-Name' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,1-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.702 NAME 'umrealmlocale' DESC 'The default locale for the realm and the default language for voice prompts' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.703 NAME 'umuserlocalelist' DESC 'The list of languages from which a subscriber can specify languages used for mailbox prompts' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.704 NAME 'umcallerlocalelist' DESC 'The list of languages from which a subscriber can specify languages used to answer calls' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.705 NAME 'umemaillocalelist' DESC 'The list of languages from which a subscriber can specify TTS language to play back emails' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.706 NAME 'umdbnkeypad' DESC 'The Dial-By-Name keypad used in a domain' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.707 NAME 'umdbnnameorder' DESC 'The Dial-By-Name name order such as whether to put first name first' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.800 NAME 'umenableautoprovisioning' DESC 'Allow auto-provisioning of accounts directly under an entry' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.801 NAME 'umautoprovisioningkeys' DESC 'Specific keys used to select an entry to auto-provision accounts under' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.802 NAME 'umautoprovisioningminkey' DESC 'Key used to select an entry to auto-provision accounts under must be greater than or equal to this' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.803 NAME 'umautoprovisioningmaxkey' DESC 'Key used to select an entry to auto-provision accounts under must be less than or equal to this' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.804 NAME 'umautoprovisioningadminpolicydn' DESC 'The admin policy DN to assign to an auto-provisioned account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.805 NAME 'umautoprovisioningmaildomain' DESC 'The mail domain to assign to an auto-provisioned account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.806 NAME 'umautoprovisioningmaillogin' DESC 'The format of the mail login to assign to an auto-provisioned account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.807 NAME 'umautoprovisioningmailprefix' DESC 'The format of the mail prefix to assign to an auto-provisioned account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.808 NAME 'umautoprovisioningmss' DESC 'The message store instance to assign to an auto-provisioned account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.809 NAME 'umautoprovisioningpassword' DESC 'The password to assign to an auto-provisioned account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.810 NAME 'umautoprovisioningpin' DESC 'Maximum number used to select an entry to auto-provision accounts under' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.811 NAME 'umautoprovisioningtargetnumberallowlist' DESC 'List of canonicalized target numbers for which auto-provisioning is allowed if prompt target is called' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", "( 1.3.6.1.4.1.2415.3.35.1.812 NAME 'umautoprovisioningnotifytypes' DESC 'The notification types to assign to an auto-provisioned account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.774.767.1.4 NAME 'notifybulkemail' DESC 'Account used for Information Provider bulk email' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.5 NAME 'notifydeleteemail' DESC 'Delete email message after notification sent' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.55 NAME 'notifybillingtype' DESC 'Site specific billing type' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.58 NAME 'notifyservicelist' DESC 'List of services permitted for use by all users in the admin policy; should not be overridden in the person entry; format: value = on or value = off' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.774.767.1.74 NAME 'notifyserviceoverride' DESC 'List of services enabled by a particular user; should only be set in the person entry and not the admin policy; format: value = on or value = off' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.774.767.1.8 NAME 'notifyfiltperuser' DESC 'User allowed to modify notification filters' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.10 NAME 'notifyfiltrulename' DESC 'Notification filter rule name' SUP name SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.12 NAME 'notifyfiltrulevalue' DESC 'Notification filter rule value' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.13 NAME 'notifyfiltdefaultaction' DESC 'Default action for notification' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.59 NAME 'notifyfiltactive' DESC 'Boolean indicating whether filter is active or not' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.60 NAME 'notifyfiltprofile' DESC 'Name of the profile associated with the rule' SUP name SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.61 NAME 'notifyfiltruleservice' DESC 'Notification filter rule service' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.62 NAME 'notifyfiltruleeventlist' DESC 'List of event types' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )", "( 1.3.6.1.4.1.2415.774.767.1.63 NAME 'notifyfiltrulelanguage' DESC 'Notification filter rule language' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.64 NAME 'notifyfiltrulescope' DESC 'Notification filter rule type' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,global,cos,shared,subscriber' )", "( 1.3.6.1.4.1.2415.774.767.1.65 NAME 'notifyfiltshareddn' DESC 'A dn referencing a shared filter rule' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.66 NAME 'notifyrulesetname' DESC 'Name of the rule set, either format or filter' SUP name SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.76 NAME 'notifyattributelist' DESC 'List of attribute names owned by a service' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.774.767.1.50 NAME 'notifyfmtruleid' DESC 'Notification Fmt Rule Id' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.17 NAME 'notifyfmtrulename' DESC 'Notification format rule name' SUP name SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.18 NAME 'notifyfmtruletype' DESC 'Notification format rule type - SOM, EOM, etc.' SUP name SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.19 NAME 'notifyfmtrulevalue' DESC 'Notification format rule value' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.26 NAME 'notifyfmtattchnone' DESC 'Display zero if no attachments' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.67 NAME 'notifyfmtrulelocale' DESC 'Locale for this format rule value' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.68 NAME 'notifyfmtrulegroupname' DESC 'Notification format rule group name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.69 NAME 'notifyfmtrulegrouptype' DESC ' Notification format rule group type default, cos' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.70 NAME 'notifyfmtrulegroupservice' DESC 'Service associated with this format rule (e.g. Calendar)' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.71 NAME 'notifyfmtrulegroupntfntype' DESC 'Notification type associated with this format rule (e.g. SMPP, SMTP)' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.72 NAME 'notifyfmtrulegroupeventtype' DESC 'Event Type associated with this format rule (e.g. NEWU, APPT)' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.73 NAME 'notifyfmtrulegroupdlvtype' DESC 'Delivery type for this format rule (e.g. SMDI, SMPPMWI, ICQ)' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.75 NAME 'notifyfmtrulegroupbasedn' DESC 'DN of format rule groups location' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.774.767.1.30 NAME 'smsmin' DESC 'Mobile ID' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.1.2 NAME 'netmailautocollect' DESC 'List of email address to collect from an outgoing email' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,all,to,none' )", "( 1.3.6.1.4.1.2415.8.1.5 NAME 'netmailmsgsperpage' DESC 'Number of messages displayed per page' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.8.1.6 NAME 'netmailreplyformat' DESC 'Default reply separator 0-line, 1-character, 2-none' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1,2' )", "( 1.3.6.1.4.1.2415.8.1.11 NAME 'netmaildefaulteditor' DESC 'Use plain text or HTML editor by default 0-Plain text, 1-HTML' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.8.1.12 NAME 'netmailmsglistcols' DESC 'Columns displayed in the message entries list' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.1.13 NAME 'netmailautopopemail' DESC 'External mail is retrieved at login, automatically or manually 0-manual, 1-login, 2-automatic' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1,2' )", "( 1.3.6.1.4.1.2415.8.1.14 NAME 'netmailpopemailacctselect' DESC 'If account is POPed 0-individual, 1-all' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.8.1.16 NAME 'netmailactivealias' DESC 'Active alias' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.1.17 NAME 'netmailpopacctdetails' DESC 'Pop account details (SMTP address, Destination Folder, Delete Message Flag, From Name, User Name, Password, Pop Server Name, Pop Server Port, Timeout, UID List, Icon Type, Password encryption type) per account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.8.1.18 NAME 'netmailabentriesperpage' DESC 'Number of address book entries to display on a web page' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.8.1.21 NAME 'netmailenablevoice' DESC 'If account can view voicemail 0-no, 1-yes' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.8.1.22 NAME 'netmailenablefax' DESC 'If account can view fax 0-no, 1-yes' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.8.1.24 NAME 'netmailcurrentver' DESC 'Indicates WebEdge Version user data is set up for' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.30.1.1 NAME 'netmailsendreturnreceipt' DESC 'Indicates return-receipt procedure' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,always,never,ask' )", "( 1.3.6.1.4.1.2415.8.30.1.3 NAME 'netmobilemailabsortby' DESC 'Contact field to sort the address book entries on a WAP page' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.30.1.4 NAME 'netmobilemailabdisplayby' DESC 'Contact field to display contacts on a WAP page' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.30.1.19 NAME 'netmailaddressbookcontactlistmax' DESC 'Maximum number of contact lists in a users address book' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.8.30.1.44 NAME 'netmailmsgviewprivacyfilter' DESC 'Determines whether HTML content in recieved messages is filtered when viewed in Webedge' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.30.1.45 NAME 'netmailrequestreturnreceipt' DESC 'Automatically send return receipt requests with outgoing messages? 0-no, 1-yes' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.8.30.1.46 NAME 'netmailautospellcheck' DESC 'Automatically spell check when sending messages? 0-no, 1-yes' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.8.30.1.14 NAME 'buddyname' SUP name )", "( 1.3.6.1.4.1.2415.8.30.1.15 NAME 'improvider' SUP name )", "( 1.3.6.1.4.1.2415.8.30.1.18 NAME 'mailwebmailchangepassword' DESC 'Is a self care user allowed to change their password 0-No, 1-Yes' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.8.30.1.5 NAME 'adminfamilymaxusers' EQUALITY integermatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.30.1.6 NAME 'adminfamilymaxstoragekb' EQUALITY integermatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.8.30.1.16 NAME 'adminrealmspecdn' DESC 'Indicates type of adminrealm' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.9 NAME 'umivraccesslastlocktime' DESC 'Subscribers last TUI access lock timestamp' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.708 NAME 'umivraccesslockperiod' DESC 'The amount of time a subscriber TUI access should be locked in seconds' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,-1-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.403 NAME 'umpnstatus' DESC 'Phone number status: A-Active, S-Suspended, L-Locked' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,A,S,L' )", "( 1.3.6.1.4.1.2415.8.30.1.48 NAME 'netmailusetrash' DESC 'Move to Trash when deleting messages? 0-no, 1-yes' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.8.30.1.49 NAME 'netmailsignaturebeforereply' DESC 'Place signature before reply? 0-after, 1-before' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.312 NAME 'umaddonservicelist' DESC 'Generic attribute to represent additional services (customization)' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.104 NAME 'umpinmaxlength' DESC 'Max number of digits allowed in pin' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.105 NAME 'umpinminlength' DESC 'Min number of digits allowed in pin' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.106 NAME 'umpinpwdrules' DESC 'Pin/password Rules' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.107 NAME 'umpinpwdlifetimedays' DESC 'Lifetime of pin/password in days' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.406 NAME 'umpnlocale' DESC 'Per phone locale' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.351 NAME 'umivrtriggerapps' DESC 'Application Server Trigger Mappings' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.352 NAME 'umivrtriggerappsdefault' DESC 'Application Server Default Trigger Mappings' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.361 NAME 'umivrmaxringbacktones' DESC 'Max number of ringback tones' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.362 NAME 'umivrringbacktoneprefs' DESC 'Ringback tone prefs: 0-feature turned off, 1-feature turned on' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.363 NAME 'umivrdefaultringbacktone' DESC 'default ringback tone' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.364 NAME 'umivravailringbacktones' DESC 'available ringback tone clips' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.365 NAME 'umivrmaxcelebgreetings' DESC 'Max number of celebrity greetings' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.366 NAME 'umivrcelebgreetingprefs' DESC 'Celebrity greeting prefs: 0-feature turned off, 1-feature turned on' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.367 NAME 'umivrdefaultcelebgreeting' DESC 'default celebrity greeting' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.368 NAME 'umivravailcelebgreetings' DESC 'available celebrity greetings' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.7.55.1.11 NAME 'transactid' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.7.55.1.12 NAME 'createhost' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.7.55.1.13 NAME 'masterserverrole' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.7.55.1.14 NAME 'metavalue' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.89 NAME 'targetobjectclass' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", "( 1.3.6.1.4.1.2415.2.2.1.143 NAME 'listheaderstoberemoved' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.52.1.10 NAME 'mailpopunifyenabled' DESC 'Determines whether if the mailbox uses the unify mode in POP sessions.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.52.1.11 NAME 'mailpopunifyhost' DESC 'Specifies the POP server host name for the old system unified POP sessions.' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.105 NAME 'mailblocksenderspabaccess' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.2.60.1.106 NAME 'mailblocksenderspabactive' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.3.35.1.318 NAME 'umservicecontrollist' DESC 'Generic attribute for controlling services at class of service level' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.407 NAME 'umid' DESC 'Text user id' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.709 NAME 'umoffsystemdeliveryoption' DESC 'Off system message delivery option: V-vpim, O-outdial' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,V,O' )", "( 1.3.6.1.4.1.2415.3.35.1.820 NAME 'umaggregatentfnprofile' DESC 'User profile to determine type of aggregated notification to send in SMS replace-if-present: L-low end, H-high end' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,L,H' )", "( 1.3.6.1.4.1.2415.3.35.1.821 NAME 'umntfnerroraction' DESC 'Action(s) to be taken when an error is encountered on notification' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.822 NAME 'umntfnretrycriteria' DESC 'Specification of the number of notification retries and retry intervals for various error cases for a particular delivery type' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.840 NAME 'umabentryid' DESC 'Unique ID of an addressbook entry' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.7.55.1.236 NAME 'updateintervalas100millisecs' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-1' )", "( 1.3.6.1.4.1.2415.7.55.1.237 NAME 'acigeneralrule' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )", "( 1.3.6.1.4.1.2415.7.55.1.238 NAME 'acigeneralruleexception' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )", "( 1.3.6.1.4.1.1466.101.120.16 NAME 'cacheable' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.60.1.107 NAME 'vmsspoplogin' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{129} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.108 NAME 'vmsspoppassword' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.109 NAME 'vmsspophost' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.110 NAME 'vmsssmtpaddress' EQUALITY caseIgnoreIA5Match ORDERING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.111 NAME 'vmsssmtphost' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.120 NAME 'vmssimaplogin' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{129} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.121 NAME 'vmssimappassword' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.122 NAME 'vmssimaphost' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.123 NAME 'vmsspopunregistered' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.124 NAME 'vmssimapunregistered' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.125 NAME 'vmssextmbox' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.2.2.1.18 NAME 'scattributeindexinfo' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 USAGE directoryOperation )", "( 1.3.6.1.4.1.2415.2.60.1.126 NAME 'mailindexhost' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.127 NAME 'mailsearchhost' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.60.1.115 NAME 'mailsmtpenforcefrom' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,default,all,header,envelope,none' )", "( 1.3.6.1.4.1.2415.3.35.1.320 NAME 'umivrplayonlymsghdrs' DESC 'Allow to play only message headers during message playback' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.321 NAME 'umivrplayaniifavailable' DESC 'Allow to play phone number during message playback' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.369 NAME 'umivrmaxcelebcligreetings' DESC 'Max number of caller specific celebrity greetings' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2147483647' )", "( 1.3.6.1.4.1.2415.3.35.1.10 NAME 'umsecondaryfaxnumber' DESC 'Secondary fax number to print to' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.319 NAME 'umivrenableplaycallbacknumber' DESC 'Allow to play the call back number before playing message' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.166 NAME 'umdestoutdialcontrol' DESC 'Destination outdial control: S-Source, D-Destination, K-Key, 0-disabled' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,S,D,K' )", "( 1.3.6.1.4.1.2415.3.35.1.302 NAME 'umivrautoprint' DESC 'Inbound fax auto-print enabled' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1,2' )", "( 1.3.6.1.4.1.2415.3.35.1.601 NAME 'umdestsearchparam' DESC 'Key for destination parameters search criteria' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.370 NAME 'umivrenablecelebgreetings' DESC 'Provision celebrity greetings: 0-feature turned off, 1-feature turned on' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.371 NAME 'umivrenableringbacktones' DESC 'Provision ringback tones: 0-feature turned off, 1-feature turned on' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.219 NAME 'umivrnonsubscribernameprefs' DESC 'non-subcriber number to greeting gid mapping' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.322 NAME 'umivrallowadminaccess' DESC 'Allow admin access: N-no access, L-limited access, F-Full access' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,N,L,F' )", "( 1.3.6.1.4.1.2415.3.35.1.323 NAME 'umivrenableadmincommercialtransfer' DESC 'Enable admin commercial transfer' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.515 NAME 'umivrholidaygreetcontrol' DESC 'Controls availability of holiday greeting feature in AA mailbox' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.516 NAME 'umivrweekendgreetcontrol' DESC 'Controls availability of weekend greeting feature in AA mailbox' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.517 NAME 'umivrafterhoursgreetcontrol' DESC 'Controls availability of After Hours greeting feature in AA mailbox' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.260 NAME 'umivrmaxcaptionsecs' DESC 'Single caption max length in secs' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.325 NAME 'umivrenablebbmailbox' DESC 'Enable BB mailbox' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.170 NAME 'umivrenableasr' DESC 'Enable ASR functionality' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.218 NAME 'umivrenablevdlcligreetings' DESC 'Enable CLI greetings for VDLs: 0-disabled, 1-enabled' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.518 NAME 'ummediaonholdsource' DESC 'URL for subscriber-specific Media-On-Hold media' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.841 NAME 'umenablecommercialgdluserprefs' DESC 'Allow commercial GDL usage: 0-disabled, 1-enabled' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.842 NAME 'umivrenablebroadcastuserprefs' DESC 'Broadcast feature at user level 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.844 NAME 'umenablebroadcast' DESC 'Broadcast feature at COS level 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.845 NAME 'umivrenablespeechtotext' DESC 'Provision TUI for speech-to-text feature 0=TUI turned OFF, 1=TUI turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.846 NAME 'umenablespeechtotext' DESC 'Enable/disable speech-to-text feature 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.847 NAME 'umspeechtotextprioritysettings' DESC 'Subscriber preference speech to text, priority settings 0=Speech to text for ALL voice messages, 1=Speech to text for URGENT voice messages only' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.2.79.1.0 NAME 'mailpopunifylogin' DESC 'Specifies the remote POP server login name in unified POP sessions.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.79.1.1 NAME 'mailpopunifypassword' DESC 'Specifies the remote POP server password in unified POP sessions.' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.2.2.1.206 NAME 'mailfolderquota' DESC 'One string with varying quotas for each of the users folders.' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4000} )", "( 1.3.6.1.4.1.2415.2.2.1.37 NAME 'mailquotatotkb' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2097151' )", "( 1.3.6.1.4.1.2415.2.2.1.38 NAME 'mailquotamaxmsgkb' EQUALITY integermatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2097151' )", "( 1.3.6.1.4.1.2415.2.52.1.1 NAME 'mailquotasendermaxmsgkb' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-VALUE-CONSTRAINT 'RANGE,0-2097151' )", "( 1.3.6.1.4.1.2415.3.35.1.324 NAME 'umivrusertype' DESC 'User Type: A-admin-commercial S-subscriber-commercial O-other' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,A,S,O,P' )", "( 1.3.6.1.4.1.2415.3.35.1.501 NAME 'umivrcallerinputtype' DESC 'Caller input type: N-name, E-extension, M-mailbox, I-ignore, V-name with asr,D-department list' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,N,E,M,I,A,V,D' )", "( 1.3.6.1.4.1.2415.3.35.1.848 NAME 'umivrenablelistenin' DESC 'Subscriber preference listen-in feature, 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.849 NAME 'umivrlistenintriggernumbers' DESC 'reason code to number mapping' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 1.3.6.1.4.1.2415.3.35.1.850 NAME 'umivrenablelivereplyconf' DESC 'Subscriber preference live-reply conference feature, 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.851 NAME 'umivrconfmediaonhold' DESC 'subscriber specific conference hold media' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.852 NAME 'umspeechtotexttranscriptionsettings' DESC 'Control speech-to-text transcription delivery 0=ALL messages, 1=NEW messages only' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.853 NAME 'umivrenableexchangetts' DESC 'Allow exchange TTS access feature to COS, 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.854 NAME 'umenableexchangetts' DESC 'Allow Subscriber exchange TTS access feature to COS, 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.855 NAME 'umexchangeserveraddress' DESC 'FQDN or IP address of MS Exchange server of a subscriber' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.856 NAME 'umexchangeserverusername' DESC 'Subscriber Username to access MS Exchange server account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.857 NAME 'umexchangeserveruserpassword' DESC 'Subscriber Password to access MS Exchange server account' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.858 NAME 'umivrenablereminderuserprefs' DESC 'Reminder feature at user level 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.859 NAME 'umenablereminder' DESC 'Reminder feature at COS level 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.860 NAME 'umenablecontentsearch' DESC 'Content feature at COS level 0=Feature turned OFF, 1=Feature turned ON' EQUALITY numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36{1} SINGLE-VALUE X-VALUE-CONSTRAINT 'CHOICE,0,1' )", "( 1.3.6.1.4.1.2415.3.35.1.861 NAME 'addressbookprovider' DESC 'Nab type' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.862 NAME 'umnabusername' DESC 'Subscriber username to access network address book' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )", "( 1.3.6.1.4.1.2415.3.35.1.863 NAME 'umnabpassword' DESC 'Subscriber password to access network address book' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )"], "matchingRules"=> ["( 1.3.6.1.4.1.2415.2.3.3.1 NAME 'caseExactIA5OrderingMatch' DESC 'SWCM defined OID for caseExactIA5OrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.3.3.2 NAME 'caseIgnoreIA5OrderingMatch' DESC 'SWCM defined OID for caseIgnoreIA5OrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.2415.2.3.3.3 NAME 'distinguishedNameSubstringMatch' DESC 'OPWV defined matching rule to do substring comparison of DNs' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", "( 2.5.13.16 NAME 'bitStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", "( 2.5.13.13 NAME 'booleanMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )", "( 2.5.13.5 NAME 'caseExactMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.5.13.6 NAME 'caseExactOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.5.13.7 NAME 'caseExactSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", "( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", "( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", "( 2.5.13.11 NAME 'caseIgnoreListMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", "( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", "( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", "( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", "( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", "( 2.5.13.14 NAME 'integerMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", "( 2.5.13.15 NAME 'integerOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", "( 2.5.13.27 NAME 'generalizedTimeMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", "( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", "( 2.5.13.8 NAME 'numericStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", "( 2.5.13.9 NAME 'numericStringOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", "( 2.5.13.10 NAME 'numericStringSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", "( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", "( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", "( 2.5.13.18 NAME 'octetStringOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", "( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", "( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )"]} activeldap-5.2.4/test/test_userls.rb0000644000004100000410000000511213464071751017555 0ustar www-datawww-datarequire 'al-test-utils' class TestUserls < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "userls") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_user ensure_delete_user("test-user") do |uid,| assert(!@user_class.exists?(uid)) assert_equal([false, "User #{uid} doesn't exist.\n"], run_command(uid)) assert(!@user_class.exists?(uid)) end end def test_list_user_no_group make_temporary_user do |user, password| assert_userls_successfully(user.uid, [], []) end end def test_list_user_have_primary_group make_temporary_group do |group| make_temporary_user(:gid_number => group.gid_number) do |user, password| assert_userls_successfully(user.uid, [group], []) end end end def test_list_user_have_groups make_temporary_group do |group1| make_temporary_group do |group2| options = {:gid_number => group2.gid_number.succ} make_temporary_user(options) do |user, password| user.groups << group1 user.groups << group2 assert_userls_successfully(user.uid, [], [group1, group2]) end end end end def test_list_user_have_groups_and_primary_group make_temporary_group do |group1| make_temporary_user(:gid_number => group1.gid_number) do |user, password| make_temporary_group do |group2| make_temporary_group do |group3| user.groups << group2 user.groups << group3 assert_userls_successfully(user.uid, [group1], [group2, group3]) end end end end end private def assert_userls_successfully(name, primary_groups, groups, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name]) user = @user_class.find(name) group_names = groups.collect {|g| "#{g.cn}"} group_infos = (primary_groups + groups).collect do |g| "#{g.cn}[#{g.gid_number}]" end result = user.to_ldif result << "Groups by name only: #{group_names.join(', ')}\n" result << "Groups: #{group_infos.join(', ')}\n" assert_equal([true, result], run_command(*args, &block)) assert(@user_class.exists?(name)) end end def assert_userls_failed(name, message, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name]) assert_equal([false, message], run_command(*args, &block)) assert(@user_class.exists?(name)) end end end activeldap-5.2.4/test/config.yaml.sample0000644000004100000410000000020013464071751020256 0ustar www-datawww-datatest: host: 127.0.0.1 base: dc=test,dc=localdomain method: :tls bind_dn: cn=user-name,dc=localdomain password: secret activeldap-5.2.4/test/test_groupdel.rb0000644000004100000410000000215013464071751020060 0ustar www-datawww-datarequire 'al-test-utils' class TestGroupdel < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "groupdel") end priority :must priority :normal def test_non_exist_group ensure_delete_group("test-group") do |name| assert(!@group_class.exists?(name)) assert_equal([false, "Group #{name} doesn't exist.\n"], run_command(name)) assert(!@group_class.exists?(name)) end end def test_delete_group make_temporary_group do |group| assert_groupdel_successfully(group.id) end end private def assert_groupdel_successfully(name, *args, &block) _wrap_assertion do assert(@group_class.exists?(name)) args.concat([name]) assert_equal([true, ""], run_command(*args, &block)) assert(!@group_class.exists?(name)) end end def assert_groupdel_failed(name, message, *args, &block) _wrap_assertion do assert(@group_class.exists?(name)) args.concat([name]) assert_equal([false, message], run_command(*args, &block)) assert(@group_class.exists?(name)) end end end activeldap-5.2.4/test/test_connection.rb0000644000004100000410000000532013464071751020400 0ustar www-datawww-datarequire 'al-test-utils' class TestConnection < Test::Unit::TestCase include AlTestUtils::Config include AlTestUtils::MockLogger def setup super end def teardown ActiveLdap::Base.clear_active_connections! super end priority :must def test_retry_limit_0_with_existent_host config = current_configuration.merge("retry_limit" => 0) ActiveLdap::Base.setup_connection(config) assert_nothing_raised do ActiveLdap::Base.find(:all) end end def test_retry_limit_0_with_nonexistent_host_with_timeout config = current_configuration.merge("host" => "192.168.29.29", "retry_limit" => 0, "timeout" => 1) ActiveLdap::Base.setup_connection(config) assert_raise(ActiveLdap::TimeoutError) do ActiveLdap::Base.find(:first) end end def test_bind_format_check connector = Class.new(ActiveLdap::Base) assert(!connector.connected?) exception = nil assert_raises(ArgumentError) do begin connector.setup_connection(:adapter => adapter, :bind_format => "uid=%s,dc=test", :allow_anonymous => false) connector.connection.connect rescue Exception exception = $! raise end end expected_message = "Unknown key: :bind_format. Valid keys are: " valid_keys = ActiveLdap::Adapter::Base::VALID_ADAPTER_CONFIGURATION_KEYS expected_message << valid_keys.collect(&:inspect).join(", ") assert_equal(expected_message, exception.message) end def test_can_reconnect? assert(!ActiveLdap::Base.connected?) config = current_configuration.merge("retry_limit" => 10) ActiveLdap::Base.setup_connection(config) connection = ActiveLdap::Base.connection assert(!connection.send(:can_reconnect?, :reconnect_attempts => 11)) config = current_configuration.merge("retry_limit" => 10) ActiveLdap::Base.setup_connection(config) connection = ActiveLdap::Base.connection assert(connection.send(:can_reconnect?, :reconnect_attempts => 10)) config = current_configuration.merge("retry_limit" => -1) ActiveLdap::Base.setup_connection(config) connection = ActiveLdap::Base.connection assert(connection.send(:can_reconnect?, :reconnect_attempts => -10)) end priority :low def test_retry_limit_0_with_nonexistent_host omit("this test will take a long time...") config = current_configuration.merge("host" => "192.168.29.29", "retry_limit" => 0) ActiveLdap::Base.setup_connection(config) assert_raise(ActiveLdap::ConnectionError) do ActiveLdap::Base.find(:first) end end end activeldap-5.2.4/test/test_groupls.rb0000644000004100000410000000617713464071751017747 0ustar www-datawww-datarequire 'al-test-utils' class TestGroupls < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "groupls") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_group ensure_delete_group("test-group") do |name| assert(!@group_class.exists?(name)) assert_equal([false, "Group #{name} doesn't exist.\n"], run_command(name)) assert(!@group_class.exists?(name)) end end def test_list_group_no_group make_temporary_group do |group| assert_groupls_successfully(group.id, []) end end def test_list_group_have_primary_members make_temporary_group do |group| make_temporary_user(:gid_number => group.gid_number) do |user1,| make_temporary_user(:gid_number => group.gid_number) do |user2,| assert_groupls_successfully(group.id, [user1, user2]) end end end end def test_list_group_have_members make_temporary_user do |user1,| make_temporary_user do |user2,| make_temporary_group do |group| group.members << user1 group.members << user2 assert_groupls_successfully(group.id, [user1, user2]) end end end end def test_list_group_have_members_and_primary_members make_temporary_group do |group| options = {:gid_number => group.gid_number} make_temporary_user(options) do |primary_user1,| make_temporary_user(options) do |primary_user2,| options1 = {:gid_number => group.gid_number.succ} options2 = {:gid_number => group.gid_number.succ.succ} make_temporary_user(options1) do |user1,| make_temporary_user(options2) do |user2,| group.members << user1 group.members << user2 assert_groupls_successfully(group.id, [primary_user1, primary_user2, user1, user2]) end end end end end end def test_list_group_have_non_exist_member make_temporary_group do |group| options = {:gid_number => group.gid_number.succ} make_temporary_user(options) do |user,| group.member_uid = [user.id] assert(group.save) assert_groupls_successfully(group.id, [user]) end end end private def assert_groupls_successfully(name, members, *args, &block) _wrap_assertion do assert(@group_class.exists?(name)) args.concat([name]) group = @group_class.find(name) members = members.collect do |m| "#{m.uid}[#{m.new_entry? ? '????' : m.uid_number}]" end result = "#{group.cn}(#{group.gid_number}): #{members.join(', ')}\n" assert_equal([true, result], run_command(*args, &block)) assert(@group_class.exists?(name)) end end def assert_groupls_failed(name, message, *args, &block) _wrap_assertion do assert(@group_class.exists?(name)) args.concat([name]) assert_equal([false, message], run_command(*args, &block)) assert(@group_class.exists?(name)) end end end activeldap-5.2.4/test/test_attributes.rb0000644000004100000410000001265413464071751020437 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestAttributes < Test::Unit::TestCase include AlTestUtils priority :must priority :normal def test_to_real_attribute_name user = @user_class.new("user") assert_equal("objectClass", user.__send__(:to_real_attribute_name, "objectclass")) assert_equal("objectClass", user.__send__(:to_real_attribute_name, "objectclass", true)) assert_nil(user.__send__(:to_real_attribute_name, "objectclass", false)) end def test_normalize_attribute assert_normalize_attribute(["usercertificate", [{"binary" => []}]], "userCertificate", []) assert_normalize_attribute(["usercertificate", [{"binary" => []}]], "userCertificate", nil) assert_normalize_attribute(["usercertificate", [{"binary" => "BINARY DATA"}]], "userCertificate", "BINARY DATA") assert_normalize_attribute(["usercertificate", [{"binary" => ["BINARY DATA"]}]], "userCertificate", {"binary" => ["BINARY DATA"]}) end def test_unnormalize_attribute assert_unnormalize_attribute({"sn" => ["Surname"]}, "sn", ["Surname"]) assert_unnormalize_attribute({"userCertificate;binary" => []}, "userCertificate", [{"binary" => []}]) assert_unnormalize_attribute({"userCertificate;binary" => ["BINARY DATA"]}, "userCertificate", [{"binary" => ["BINARY DATA"]}]) assert_unnormalize_attribute({ "sn" => ["Yamada"], "sn;lang-ja" => ["山田"], "sn;lang-ja;phonetic" => ["やまだ"] }, "sn", ["Yamada", {"lang-ja" => ["山田", {"phonetic" => ["やまだ"]}]}]) end private def assert_normalize_attribute(expected, name, value) assert_equal(expected, ActiveLdap::Base.normalize_attribute(name, value)) end def assert_unnormalize_attribute(expected, name, value) assert_equal(expected, ActiveLdap::Base.unnormalize_attribute(name, value)) end class TestBlankValue < self private def assert_blank_value(value) assert_true(ActiveLdap::Base.blank_value?(value), "value: <#{value.inspect}>") end def assert_not_blank_value(value) assert_false(ActiveLdap::Base.blank_value?(value), "value: <#{value.inspect}>") end class TestHash < self def test_empty assert_blank_value({}) end def test_have_elements assert_not_blank_value({"name" => "Taro", "age" => 29}) end def test_have_blank_element assert_not_blank_value({"name" => nil, "age" => 29}) end def test_all_blank_elements assert_blank_value({"name" => nil, "age" => nil}) end end class TestArray < self def test_empty assert_blank_value([]) end def test_have_elements assert_not_blank_value(["Taro", "Jiro"]) end def test_have_blank_element assert_not_blank_value(["Taro", nil]) end def test_all_blank_elements assert_blank_value([nil, nil]) end end class TestString < self def test_empty assert_blank_value("") end def test_only_spaces assert_blank_value(" \t\n") end def test_have_non_spaces assert_not_blank_value("Taro") end end class TestBoolean < self def test_true assert_not_blank_value(true) end def test_false assert_not_blank_value(true) end end end class TestMassAssignment < self def test_forbid attributes = {:cn => "Alice"} def attributes.permitted? false end assert_raise(ActiveModel::ForbiddenAttributesError) do @user_class.new(attributes) end end def test_permit attributes = {:cn => "Alice"} def attributes.permitted? true end alice = @user_class.new(attributes) assert_equal("Alice", alice.cn) end def test_forbid_object_class classes = @user_class.required_classes + ["inetOrgPerson"] user = @user_class.new(:uid => "XXX", :object_class => classes) assert_equal(["inetOrgPerson"], user.classes - @user_class.required_classes) user = @user_class.new(:uid => "XXX", :object_class => ['inetOrgPerson']) assert_equal(["inetOrgPerson"], user.classes - @user_class.required_classes) user = @user_class.new("XXX") assert_equal([], user.classes - @user_class.required_classes) user.attributes = {:object_class => classes} assert_equal([], user.classes - @user_class.required_classes) end def test_rename make_temporary_user(:simple => true) do |user,| assert_true(user.update_attributes(:id => "user2")) assert_equal("user2", user.id) end end end end activeldap-5.2.4/test/test_adapter.rb0000644000004100000410000001176013464071751017666 0ustar www-datawww-datarequire 'al-test-utils' class TestAdapter < Test::Unit::TestCase include AlTestUtils def setup end def teardown end priority :must def test_operator assert_parse_filter("(uid=Alice)", ["uid", "=", "Alice"]) assert_parse_filter("(uid~=Alice)", ["uid", "~=", "Alice"]) assert_parse_filter("(uidNumber>=1000)", ["uidNumber", ">=", "1000"]) assert_parse_filter("(uidNumber<=1000)", ["uidNumber", "<=", "1000"]) assert_parse_filter("(&(uid~=Alice)(uid~=Bob))", ["uid", "~=", "Alice", "Bob"]) assert_parse_filter("(uid~=Alice)", [["uid", "~=", "Alice"]]) assert_parse_filter("(|(uid~=Alice)(uid~=Bob))", [:or, ["uid", "~=", "Alice"], ["uid", "~=", "Bob"]]) assert_parse_filter("(|(uid~=Alice)(uid~=Bob))", [:or, ["uid", "~=", "Alice", "Bob"]]) end priority :normal def test_filter_with_escaped_character assert_parse_filter("(uid=Alice\\28Bob)", {:uid => "Alice(Bob"}) assert_parse_filter("(uid=Alice\\29Bob)", {:uid => "Alice)Bob"}) assert_parse_filter("(uid=Alice\\29Bob\\28)", {:uid => "Alice)Bob("}) assert_parse_filter("(uid=Alice\\28\\29Bob)", {:uid => "Alice()Bob"}) assert_parse_filter("(uid=Alice*Bob)", {:uid => "Alice*Bob"}) assert_parse_filter("(uid=Alice\\2ABob)", {:uid => "Alice**Bob"}) assert_parse_filter("(uid=Alice\\2A*\\5CBob)", {:uid => "Alice***\\Bob"}) assert_parse_filter("(uid=Alice\\5C\\2A*Bob)", {:uid => "Alice\\***Bob"}) assert_parse_filter("(uid=Alice\\3ABob)", {:uid => "Alice:Bob"}) end def test_empty_filter assert_parse_filter(nil, nil) assert_parse_filter(nil, "") assert_parse_filter(nil, " ") end def test_simple_filter assert_parse_filter("(objectClass=*)", "objectClass=*") assert_parse_filter("(objectClass=*)", "(objectClass=*)") assert_parse_filter("(&(uid=bob)(objectClass=*))", "(&(uid=bob)(objectClass=*))") assert_parse_filter("(objectClass=*)", {:objectClass => "*"}) assert_parse_filter("(&(objectClass=*)(uid=bob))", {:uid => "bob", :objectClass => "*"}) assert_parse_filter("(&(uid=bob)(objectClass=*))", [:and, "uid=bob", "objectClass=*"]) assert_parse_filter("(&(uid=bob)(objectClass=*))", [:&, "uid=bob", "objectClass=*"]) assert_parse_filter("(|(uid=bob)(objectClass=*))", [:or, "uid=bob", "objectClass=*"]) assert_parse_filter("(|(uid=bob)(objectClass=*))", [:|, "uid=bob", "objectClass=*"]) end def test_multi_value_filter assert_parse_filter("(&(objectClass=top)(objectClass=posixAccount))", {:objectClass => ["top", "posixAccount"]}) assert_parse_filter("(&(objectClass=top)(objectClass=posixAccount))", [[:objectClass, "top"], [:objectClass, "posixAccount"]]) assert_parse_filter("(&(objectClass=top)(objectClass=posixAccount))", [[:objectClass, ["top", "posixAccount"]]]) end def test_nested_filter assert_parse_filter("(&(objectClass=*)(uid=bob))", [:and, {:uid => "bob", :objectClass => "*"}]) assert_parse_filter("(&(objectClass=*)(|(uid=bob)(uid=alice)))", [:and, {:objectClass => "*"}, [:or, [:uid, "bob"], [:uid, "alice"]]]) assert_parse_filter("(&(objectClass=*)(|(uid=bob)(uid=alice)))", [:and, {:objectClass => "*", :uid => [:or, "bob", "alice"]}]) assert_parse_filter("(&(gidNumber=100001)" + "(|(uid=temp-user1)(uid=temp-user2)))", [:and, [:and, {"gidNumber" => ["100001"]}], [:or, {"uid" => ["temp-user1", "temp-user2"]}]]) assert_parse_filter("(&(gidNumber=100001)" + "(objectClass=person)(objectClass=posixAccount))", [:and, [:or, ["gidNumber", "100001"]], ["objectClass", "person"], ["objectClass", "posixAccount"]]) assert_parse_filter("(&(!(|(gidNumber=100001)(gidNumber=100002)))" + "(objectClass=person)(!(objectClass=posixAccount)))", [:and, [:not, [:or, ["gidNumber", "100001", "100002"]]], ["objectClass", "person"], [:not, ["objectClass", "posixAccount"]]]) end def test_invalid_operator assert_raises(ArgumentError) do assert_parse_filter("(&(objectClass=*)(uid=bob))", [:xxx, {:uid => "bob", :objectClass => "*"}]) end end private def assert_parse_filter(expected, filter) adapter = ActiveLdap::Adapter::Base.new assert_equal(expected, adapter.send(:parse_filter, filter)) end end activeldap-5.2.4/test/test_userdel.rb0000644000004100000410000000222713464071751017707 0ustar www-datawww-datarequire 'al-test-utils' class TestUserdel < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "userdel") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_user ensure_delete_user("test-user") do |uid,| assert(!@user_class.exists?(uid)) assert_equal([false, "User #{uid} doesn't exist.\n"], run_command(uid)) assert(!@user_class.exists?(uid)) end end def test_delete_user make_temporary_user do |user, password| assert_userdel_successfully(user.uid) end end private def assert_userdel_successfully(name, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name]) assert_equal([true, ""], run_command(*args, &block)) assert(!@user_class.exists?(name)) end end def assert_userdel_failed(name, message, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name]) assert_equal([false, message], run_command(*args, &block)) assert(@user_class.exists?(name)) end end end activeldap-5.2.4/test/test_associations.rb0000644000004100000410000006263313464071751020752 0ustar www-datawww-datarequire 'al-test-utils' class TestAssociations < Test::Unit::TestCase include AlTestUtils priority :must def test_belongs_to_replace_with_string make_temporary_user do |user,| make_temporary_group do |group1| make_temporary_group do |group2| user.groups = [group1, group2] user.save! user.groups = [group2.cn] group1.reload group2.reload assert_equal([group2], user.groups.to_a) assert_equal([], group1.member_uid(true)) assert_equal([user.id], group2.member_uid(true)) end end end end priority :normal def test_has_many_of_self @user_class.has_many(:references, :class_name => "User", :primary_key => "dn", :foreign_key => "seeAlso") @user_class.set_associated_class(:references, @user_class) make_temporary_user do |user1, password1| make_temporary_user(:see_also => user1.dn.to_s) do |user2, password2| make_temporary_user(:see_also => user2.dn.to_s) do |user3, password3| make_temporary_user(:see_also => user2.dn.to_s) do |user4, password4| make_temporary_user(:see_also => user1.dn.to_s) do |user5, password5| user1_references = user1.references.collect {|r| r.dn.to_s} user2_references = user2.references.collect {|r| r.dn.to_s} user1_expected_references = [user2, user5].collect {|r| r.dn.to_s} user2_expected_references = [user3, user4].collect {|r| r.dn.to_s} assert_equal(user1_expected_references, user1_references) assert_equal(user2_expected_references, user2_references) end end end end end end def test_belongs_to_add_with_string make_temporary_user do |user,| make_temporary_group do |group1| make_temporary_group do |group2| assert_equal([[], []], [group1.members.collect(&:cn), group2.members.collect(&:cn)]) user.groups = [group1.cn, group2.cn] user.save! group1.reload group2.reload assert_equal([[user.cn], [user.cn]], [group1.members.collect(&:cn), group2.members.collect(&:cn)]) end end end end def test_has_many_delete_required_attribute make_temporary_group do |group| make_temporary_user do |user,| user.primary_group = group assert_raise(ActiveLdap::RequiredAttributeMissed) do group.primary_members.delete(user) end end end end def test_to_xml make_temporary_user do |user,| make_temporary_group do |group1| make_temporary_group do |group2| user.groups = [group1, group2] assert_equal(<<-EOX, user.groups.to_xml(:root => "groups")) #{group1.dn} #{group1.cn} #{group1.gid_number} #{user.cn} posixGroup #{group2.dn} #{group2.cn} #{group2.gid_number} #{user.cn} posixGroup EOX end end end end def test_belongs_to_with_invalid_dn_attribute_value make_temporary_user do |user,| make_temporary_group do |group| user.primary_group = group user.uid = "#" assert_nothing_raised do user.primary_group.reload end end end end def test_belongs_to_foreign_key_before_1_1_0 ActiveSupport::Deprecation.silence do @group_class.belongs_to :related_users, :many => "seeAlso", :foreign_key => "dn" end @group_class.set_associated_class(:related_users, @user_class) make_temporary_user do |user,| make_temporary_group do |group| user.see_also = group.dn user.save! group = @group_class.find(group.id) assert_equal([user.dn], group.related_users.collect(&:dn)) end end end def test_has_many_wrap_with_nonexistent_entry @user_class.has_many :references, :wrap => "seeAlso", :primary_key => "dn" @user_class.set_associated_class(:references, @group_class) @group_class.belongs_to :related_users, :many => "seeAlso", :primary_key => "dn" @group_class.set_associated_class(:related_users, @user_class) make_temporary_user do |user,| make_temporary_group do |group1| make_temporary_group do |group2| user.references = [group1, group2] group3_dn = group2.dn.to_s.sub(/cn=(.*?),/, "cn=\\1-nonexistent,") user.see_also += [group3_dn] user.save! group3_dn = dn(group3_dn) user = @user_class.find(user.dn) assert_equal([group1.dn, group2.dn, group3_dn], user.see_also) assert_equal([group1.dn, group2.dn, group3_dn], user.references.collect(&:dn)) assert_equal([group1.gid_number, group2.gid_number, nil], user.references.collect(&:gid_number)) assert_equal([false, false, true], user.references.collect(&:new_entry?)) end end end end def test_has_many_wrap_with_dn_value @user_class.has_many :references, :wrap => "seeAlso", :primary_key => "dn" @user_class.set_associated_class(:references, @group_class) @group_class.belongs_to :related_users, :many => "seeAlso", :primary_key => "dn" @group_class.set_associated_class(:related_users, @user_class) make_temporary_user do |user,| make_temporary_group do |group1| make_temporary_group do |group2| make_temporary_group do |group3| entries = [user, group1, group2, group3] user.references << group1 user, group1, group2, group3 = reload_entries(*entries) assert_references([[group1]], [user]) assert_related_users([user], group1) assert_related_users([], group2) assert_related_users([], group3) user.references = [group2, group3] user, group1, group2, group3 = reload_entries(*entries) assert_references([[group2, group3]], [user]) assert_related_users([], group1) assert_related_users([user], group2) assert_related_users([user], group3) user.references.delete(group2) user, group1, group2, group3 = reload_entries(*entries) assert_references([[group3]], [user]) assert_related_users([], group1) assert_related_users([], group2) assert_related_users([user], group3) end end end end end def test_belongs_to_many_with_dn_value @user_class.has_many :references, :wrap => "seeAlso", :primary_key => "dn" @user_class.set_associated_class(:references, @group_class) @group_class.belongs_to :related_users, :many => "seeAlso", :primary_key => "dn" @group_class.set_associated_class(:related_users, @user_class) make_temporary_group do |group| make_temporary_user do |user1,| make_temporary_user do |user2,| make_temporary_user do |user3,| entries = [group, user1, user2, user3] group.related_users = [user1, user2] group, user1, user2, user3 = reload_entries(*entries) assert_references([[group], [group], []], [user1, user2, user3]) assert_related_users([user1, user2], group) group.related_users << user3 group, user1, user2, user3 = reload_entries(*entries) assert_references([[group], [group], [group]], [user1, user2, user3]) assert_related_users([user1, user2, user3], group) group.related_users.delete(user1) group, user1, user2, user3 = reload_entries(*entries) assert_references([[], [group], [group]], [user1, user2, user3]) assert_related_users([user2, user3], group) group.related_users = [] group, user1, user2, user3 = reload_entries(*entries) assert_references([[], [], []], [user1, user2, user3]) assert_related_users([], group) end end end end end def test_belongs_to_many_with_dn_key @user_class.belongs_to :dn_groups, :many => "memberUid", :primary_key => "dn" @user_class.set_associated_class(:dn_groups, @group_class) @group_class.has_many :dn_members, :wrap => "memberUid", :primary_key => "dn" @group_class.set_associated_class(:dn_members, @user_class) make_temporary_group do |group| make_temporary_user do |user1,| make_temporary_user do |user2,| make_temporary_user do |user3,| entries = [group, user1, user2, user3] user1.dn_groups << group group, user1, user2, user3 = reload_entries(*entries) assert_dn_groups([[group], [], []], [user1, user2, user3]) assert_dn_members([user1], group) user2.dn_groups = [group] group, user1, user2, user3 = reload_entries(*entries) assert_dn_groups([[group], [group], []], [user1, user2, user3]) assert_dn_members([user1, user2], group) user1.dn_groups = [] group, user1, user2, user3 = reload_entries(*entries) assert_dn_groups([[], [group], []], [user1, user2, user3]) assert_dn_members([user2], group) user2.dn_groups.delete(group) group, user1, user2, user3 = reload_entries(*entries) assert_dn_groups([[], [], []], [user1, user2, user3]) assert_dn_members([], group) end end end end end def test_belongs_to_many_add_by_dn_attribute make_temporary_group do |group1| make_temporary_group do |group2| make_temporary_user do |user,| user.update_attribute(:cn, "new #{user.cn}") user.groups = [group1] assert_equal([group1.id].sort, user.groups.collect {|g| g.id}.sort) user.groups << group2.id assert_equal([group1.id, group2.id].sort, user.groups.collect {|g| g.id}.sort) end end end end def test_belongs_to_many_delete make_temporary_group do |group1| make_temporary_group do |group2| make_temporary_user do |user,| user.update_attribute(:cn, "new #{user.cn}") user.groups = [group1, group2] assert_equal([group1.id, group2.id].sort, user.groups.collect {|g| g.id}.sort) assert_equal([user.id].sort, group1.member_uid(true)) assert_equal([user.id].sort, group2.member_uid(true)) user.groups = [] assert_equal([], user.groups.to_a) assert_equal([], group1.member_uid(true)) assert_equal([], group2.member_uid(true)) end end end end def test_belongs_to_before_save make_temporary_group do |group1| make_temporary_group do |group2| ensure_delete_group(group2.cn.succ) do |group3_name| group3 = @group_class.new(group3_name) group3.gid_number = group2.gid_number.succ make_temporary_user(:gid_number => group1.gid_number) do |user,| assert_equal(group1.gid_number, user.primary_group.gid_number) assert_equal(group1.gid_number, user.gid_number) user.primary_group = group2 assert_equal(group2.gid_number, user.primary_group.gid_number) assert_equal(group2.gid_number, user.gid_number) user_in_ldap = @user_class.find(user.id) assert_equal(group1.gid_number, user_in_ldap.primary_group.gid_number) assert_equal(group1.gid_number, user_in_ldap.gid_number) assert(group3.new_entry?) user.primary_group = group3 assert_equal(group3.gid_number, user.primary_group.gid_number) assert_equal(group2.gid_number, user.gid_number) assert(user.save) assert_equal(group3.gid_number, user.gid_number) user_in_ldap = @user_class.find(user.id) assert(!user_in_ldap.primary_group.exists?) assert(group3.save) assert(user_in_ldap.primary_group.exists?) assert_equal(group3.gid_number, user_in_ldap.primary_group.gid_number) end end end end end def test_extend mod = Module.new mod.__send__(:mattr_accessor, :called) mod.__send__(:define_method, :replace) do |entries| super(entries) mod.called = true end mod.called = false @group_class.send(:undef_method, :members, :members=, :__make_members) @group_class.has_many :members, :wrap => "memberUid", :extend => mod @group_class.set_associated_class(:members, @user_class) make_temporary_group do |group| gid_number1 = group.gid_number.to_i + 1 make_temporary_user(:gid_number => gid_number1) do |user1, password1| user1.update_attribute(:cn, "new #{user1.cn}") assert(!mod.called) group.members = [user1] assert(mod.called) end end end def test_has_many_wrap_assign make_temporary_group do |group| gid_number1 = group.gid_number.to_i + 1 gid_number2 = group.gid_number.to_i + 2 make_temporary_user(:gid_number => gid_number1) do |user1, password1| make_temporary_user(:gid_number => gid_number2) do |user2, password2| user1.update_attribute(:cn, "new #{user1.cn}") user2.update_attribute(:cn, "new #{user2.cn}") assert_equal([], group.members.to_a) assert_equal([], group.member_uid(true)) assert_equal(gid_number1, user1.gid_number.to_i) assert_equal(gid_number2, user2.gid_number.to_i) group.members = [user1, user2] assert_equal([user1.uid, user2.uid].sort, group.members.collect {|x| x.uid}.sort) assert_equal([user1.uid, user2.uid].sort, group.member_uid.sort) assert_equal(gid_number2, user2.gid_number.to_i) group.members = [user1] assert_equal([user1.uid].sort, group.members.collect {|x| x.uid}.sort) assert_equal(user1.uid, group.member_uid) assert_equal(gid_number1, user1.gid_number.to_i) end end end end def test_has_many_wrap_assign_new_entry make_temporary_user do |user1, | make_temporary_user do |user2, | ensure_delete_group('test_new_group') do |cn| group = @group_class.new(:cn => cn, :gid_number => default_gid) assert_equal([], group.members.to_a) assert_equal([], group.member_uid(true)) group.members = [user1, user2] assert group.new_entry? assert_equal([user1.uid, user2.uid].sort, group.members.map {|x| x.uid }.sort) assert_equal([user1.uid, user2.uid].sort, group.member_uid(true).sort) group.members = [user2] assert group.new_entry? assert_equal([user2.uid], group.members.map {|x| x.uid }) assert_equal(user2.uid, group.member_uid) group.members << user1 assert group.new_entry? assert_equal([user1.uid, user2.uid].sort, group.members.map {|x| x.uid }.sort) assert_equal([user1.uid, user2.uid].sort, group.member_uid.sort) assert(group.save) group = @group_class.find(cn) assert_equal([user1.uid, user2.uid].sort, group.members.map {|x| x.uid }.sort) assert_equal([user1.uid, user2.uid].sort, group.member_uid.sort) end end end end def test_has_many_validation group_class = Class.new(ActiveLdap::Base) group_class.ldap_mapping :prefix => "ou=Groups", :scope => :sub, :classes => ["posixGroup"] assert_raises(ArgumentError) do group_class.has_many :users, :unknown_name => "value" end mod = Module.new assert_nothing_raised do group_class.has_many :users, :class_name => "User" group_class.has_many :members, :class => @user_class, :wrap => "memberUid", :extend => mod group_class.has_many :primary_members, :class => @user_class, :primary_key => "gidNumber", :foreign_key => "gidNumber", :extend => mod end end def test_belongs_to_validation user_class = Class.new(ActiveLdap::Base) user_class.ldap_mapping :dn_attribute => "uid", :prefix => "ou=Users", :scope => :sub, :classes => ["posixAccount", "person"] assert_raises(ArgumentError) do user_class.belongs_to :groups, :unknown_name => "value" end mod = Module.new assert_nothing_raised do user_class.belongs_to :string_groups, :class_name => "Group" user_class.belongs_to :groups, :class => @group_class, :many => "memberUid", :extend => mod user_class.belongs_to :primary_group, :class => @group_class, :foreign_key => "gidNumber", :primary_key => "gidNumber", :extend => mod end end def test_has_many_assign make_temporary_group do |group| gid_number1 = group.gid_number.to_i + 1 gid_number2 = group.gid_number.to_i + 2 make_temporary_user(:gid_number => gid_number1) do |user1, password1| make_temporary_user(:gid_number => gid_number2) do |user2, password2| assert_equal(gid_number1, user1.gid_number.to_i) group.primary_members = [user1] assert_equal([user1.uid].sort, group.primary_members.collect {|x| x.uid}.sort) assert_equal(group.gid_number, user1.gid_number) assert_equal(gid_number2, user2.gid_number.to_i) group.primary_members = [user1, user2] assert_equal([user1.uid, user2.uid].sort, group.primary_members.collect {|x| x.uid}.sort) assert_equal(group.gid_number, user2.gid_number) assert_raises(ActiveLdap::RequiredAttributeMissed) do group.primary_members = [] end assert_raises(ActiveLdap::RequiredAttributeMissed) do group.primary_members = [user1] end assert_raises(ActiveLdap::RequiredAttributeMissed) do group.primary_members = [user2] end assert_nothing_raised do group.primary_members = [user1, user2] end end end end end def test_belongs_to_many make_temporary_group do |group1| make_temporary_group do |group2| make_temporary_user do |user,| user.update_attribute(:cn, "new #{user.cn}") assert_equal([], user.groups.to_a) assert_equal([], group1.member_uid(true)) assert_equal([], group2.member_uid(true)) user.groups << group1 assert_equal([group1.id].sort, user.groups.collect {|g| g.id}.sort) assert_equal([user.id].sort, group1.member_uid(true)) assert_equal([].sort, group2.member_uid(true)) user.groups << group2 assert_equal([group1.id, group2.id].sort, user.groups.collect {|g| g.id}.sort) assert_equal([user.id].sort, group1.member_uid(true)) assert_equal([user.id].sort, group2.member_uid(true)) end end end end def test_belongs_to_many_non_exist make_temporary_group do |group| ensure_delete_user("temp-user1") do |user1,| options = {:uid => "temp-user2", :gid_number => group.gid_number.succ} make_temporary_user(options) do |user2,| ensure_delete_user("temp-user3") do |user3,| group.members << user2 group.member_uid = [user1, group.member_uid, user3] assert(group.save) group.members.reload assert_equal([user1, user2.id, user3], group.members.collect {|g| g.id}) assert_equal([true, false, true], group.members.collect {|g| g.new_entry?}) end end end end end def test_belongs_to make_temporary_group do |group| gid_number = group.gid_number.to_i + 1 make_temporary_user(:gid_number => group.gid_number) do |user_in_group,| make_temporary_user(:gid_number => gid_number) do |user_not_in_group,| assert(user_in_group.primary_group.reload) assert(user_in_group.primary_group.loaded?) assert_equal(group.gid_number, user_in_group.gid_number) assert_equal(group.gid_number, user_in_group.primary_group.gid_number) assert(!user_not_in_group.primary_group.loaded?) assert_equal(gid_number, user_not_in_group.gid_number.to_i) assert_not_equal(group.gid_number, user_not_in_group.gid_number) user_not_in_group.primary_group = group assert(user_not_in_group.primary_group.loaded?) assert(user_not_in_group.primary_group.updated?) assert_equal(group.gid_number, user_not_in_group.gid_number) assert_equal(group.gid_number, user_not_in_group.primary_group.gid_number) assert_not_equal(gid_number, user_not_in_group.gid_number.to_i) assert_equal(group.gid_number, user_in_group.gid_number) assert_equal(group.gid_number, user_in_group.primary_group.gid_number) end end end end def test_has_many_wrap make_temporary_group do |group| gid_number1 = group.gid_number.to_i + 1 gid_number2 = group.gid_number.to_i + 2 make_temporary_user(:gid_number => gid_number1) do |user1, password1| make_temporary_user(:gid_number => gid_number2) do |user2, password2| user1.update_attribute(:cn, "new #{user1.cn}") user2.update_attribute(:cn, "new #{user2.cn}") assert_equal([], group.members.to_a) assert_equal([], group.member_uid(true)) assert_equal(gid_number1, user1.gid_number.to_i) group.members << user1 assert_equal([user1.uid].sort, group.members.collect {|x| x.uid}.sort) assert_equal(user1.uid, group.member_uid) assert_equal(gid_number1, user1.gid_number.to_i) assert_equal(gid_number2, user2.gid_number.to_i) group.members << user2 assert_equal([user1.uid, user2.uid].sort, group.members.collect {|x| x.uid}.sort) assert_equal([user1.uid, user2.uid].sort, group.member_uid.sort) assert_equal(gid_number2, user2.gid_number.to_i) end end end end def test_has_many make_temporary_group do |group| gid_number1 = group.gid_number.to_i + 1 gid_number2 = group.gid_number.to_i + 2 make_temporary_user(:gid_number => gid_number1) do |user1, password1| make_temporary_user(:gid_number => gid_number2) do |user2, password2| assert_equal([], group.primary_members.to_a) assert_equal(gid_number1, user1.gid_number.to_i) group.primary_members << user1 assert_equal([user1.uid].sort, group.primary_members.collect {|x| x.uid}.sort) assert_equal(group.gid_number, user1.gid_number) assert_equal(gid_number2, user2.gid_number.to_i) group.primary_members << user2 assert_equal([user1.uid, user2.uid].sort, group.primary_members.collect {|x| x.uid}.sort) assert_equal(group.gid_number, user2.gid_number) end end end end private def reload_entries(*entries) entries.collect do |entry| entry.class.find(entry[entry.dn_attribute]) end end def assert_groups_relation(expected_groups_values, entries, relation_name) expected_groups_values = expected_groups_values.collect do |groups| groups.collect(&:cn).sort end actual_groups_values = entries.collect do |entry| entry.send(relation_name).collect(&:cn).sort end assert_equal(expected_groups_values, actual_groups_values) end def assert_users_relation(expected_users, group, relation_name) assert_equal(expected_users.collect(&:cn).sort, group.send(relation_name).collect(&:cn).sort) end def assert_references(expected_groups_values, users) assert_groups_relation(expected_groups_values, users, :references) end def assert_related_users(expected_users, group) assert_users_relation(expected_users, group, :related_users) end def assert_dn_groups(expected_groups_values, users) assert_groups_relation(expected_groups_values, users, :dn_groups) end def assert_dn_members(expected_users, group) assert_users_relation(expected_users, group, :dn_members) end end activeldap-5.2.4/test/test_load.rb0000644000004100000410000001023513464071751017161 0ustar www-datawww-datarequire 'al-test-utils' class TestLoad < Test::Unit::TestCase include AlTestUtils priority :must def test_load_modify_record ldif = ActiveLdap::LDIF.new make_temporary_user do |user, password| user.display_name = "Display Name" assert(user.save) user = @user_class.find(user.dn) assert_equal("Display Name", user.display_name) record = ActiveLdap::LDIF::ModifyRecord.new(user.dn) ldif << record original_home_directory = user.home_directory new_home_directory = "#{original_home_directory}-new" record.add_operation(:delete, "homeDirectory", [], {}) record.add_operation(:add, "homeDirectory", [], {"homeDirectory" => [new_home_directory]}) original_descriptions = user.description(true) new_description = "new description" record.add_operation(:add, "description", [], {"description" => [new_description]}) record.add_operation(:delete, "DisplayName", [], {}) new_sn = ["New SN1", "New SN2"] record.add_operation(:replace, "sn", [], {"sn" => new_sn}) ActiveLdap::Base.load(ldif.to_s) user = @user_class.find(user.dn) assert_equal(new_home_directory, user.home_directory) assert_equal(original_descriptions + [new_description], user.description(true)) assert_nil(user.display_name) assert_equal(new_sn, user.sn) end end def test_load_move_dn_record assert_load_move_dn_record(ActiveLdap::LDIF::ModifyDNRecord) assert_load_move_dn_record(ActiveLdap::LDIF::ModifyRDNRecord) end def test_load_copy_dn_record assert_load_copy_dn_record(ActiveLdap::LDIF::ModifyDNRecord) assert_load_copy_dn_record(ActiveLdap::LDIF::ModifyRDNRecord) end def test_load_delete_record ldif = ActiveLdap::LDIF.new make_temporary_user do |user, password| record = ActiveLdap::LDIF::DeleteRecord.new(user.dn) ldif << record assert_true(@user_class.exists?(user.dn)) ActiveLdap::Base.load(ldif.to_s) assert_false(@user_class.exists?(user.dn)) end end def test_load_add_record ldif = ActiveLdap::LDIF.new make_temporary_user do |user, password| new_description = "new description" attributes = { "description" => [new_description] } original_descriptions = user.description(true) record = ActiveLdap::LDIF::AddRecord.new(user.dn, [], attributes) ldif << record ActiveLdap::Base.load(ldif.to_s) user.reload assert_equal(original_descriptions + [new_description], user.description(true)) end end def test_load_content_records ldif = ActiveLdap::LDIF.new 2.times do make_temporary_user do |user, password| ldif << ActiveLdap::LDIF.parse(user.to_ldif).records[0] end end original_n_users = @user_class.count ActiveLdap::Base.load(ldif.to_s) assert_equal(2, @user_class.count - original_n_users) end priority :normal private def assert_load_copy_dn_record(record_class) ldif = ActiveLdap::LDIF.new make_temporary_user do |user, password| new_rdn = "uid=XXX" ensure_delete_user(new_rdn) do record = record_class.new(user.dn, [], new_rdn, false) ldif << record assert_true(@user_class.exists?(user.dn)) assert_false(@user_class.exists?(new_rdn)) ActiveLdap::Base.load(ldif.to_s) assert_true(@user_class.exists?(user.dn)) assert_true(@user_class.exists?(new_rdn)) assert_equal(user.cn, @user_class.find(new_rdn).cn) end end end def assert_load_move_dn_record(record_class) ldif = ActiveLdap::LDIF.new make_temporary_user do |user, password| new_rdn = "uid=XXX" ensure_delete_user(new_rdn) do record = record_class.new(user.dn, [], new_rdn, true) ldif << record assert_true(@user_class.exists?(user.dn)) assert_false(@user_class.exists?(new_rdn)) ActiveLdap::Base.load(ldif.to_s) assert_false(@user_class.exists?(user.dn)) assert_true(@user_class.exists?(new_rdn)) assert_equal(user.cn, @user_class.find(new_rdn).cn) end end end end activeldap-5.2.4/test/test_base.rb0000644000004100000410000012007313464071751017156 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestBase < Test::Unit::TestCase include AlTestUtils priority :must def test_search_colon_value make_temporary_group(:cn => "temp:group") do |group| assert_equal("temp:group", group.cn) assert_not_nil(@group_class.find("temp:group")) end end priority :normal def test_lower_case_object_class fixture_file = fixture("lower_case_object_class_schema.rb") schema_entries = eval(File.read(fixture_file)) schema = ActiveLdap::Schema.new(schema_entries) target_class = Class.new(ActiveLdap::Base) do ldap_mapping :dn_attribute => "umpn", :prefix => "cn=site", :classes => ['top', 'umphone', 'umphonenumber'] end target_class.connection.instance_variable_set("@schema", schema) target_class.connection.instance_variable_set("@entry_attributes", {}) target = target_class.send(:instantiate, [ "umpn=1.555.5551234,#{target_class.base}", { "umpn" => "1.555.5551234", "objectclass" => ["top", "umphone", "umphonenumber"], } ]) assert_equal("1.555.5551234", target.umpn) end def test_set_and_get_false user = @user_class.new user.sn = false assert_equal(false, user.sn) end def test_modify_entry_with_attribute_with_nested_options make_temporary_user(:simple => true) do |user,| user.sn = ["Yamada", {"lang-ja" => ["山田", {"phonetic" => ["やまだ"]}]}] assert_nothing_raised do user.save! end end end def test_add_entry_with_attribute_with_nested_options ensure_delete_user("temp-user") do |uid,| user = @user_class.new user.cn = uid user.uid = uid user.uid_number = 1000 user.gid_number = 1000 user.home_directory = "/home/#{uid}" assert_not_predicate(user, :valid?) user.sn = ["Yamada", {"lang-ja" => ["山田", {"phonetic" => ["やまだ"]}]}] assert_predicate(user, :valid?) assert_nothing_raised do user.save! end end end def test_attributes make_temporary_group do |group| assert_equal({ "cn" => group.cn, "gidNumber" => group.gidNumber, "objectClass" => group.classes, }, group.attributes) end end def test_rename_with_superior make_ou("sub,ou=users") make_temporary_user(:simple => true) do |user,| user.id = "user2,ou=sub,#{@user_class.base}" assert_true(user.save) found_user = nil assert_nothing_raised do found_user = @user_class.find("user2") end base = @user_class.base assert_equal("#{@user_class.dn_attribute}=user2,ou=sub,#{base}", found_user.dn.to_s) end end def test_rename make_temporary_user(:simple => true) do |user,| assert_not_equal("user2", user.id) assert_raise(ActiveLdap::EntryNotFound) do @user_class.find("user2") end user.id = "user2" assert_true(user.save) assert_equal("user2", user.id) found_user = nil assert_nothing_raised do found_user = @user_class.find("user2") end assert_equal("user2", found_user.id) end end def test_operational_attributes make_temporary_group do |group| dn, attributes = @group_class.search(:attributes => ["*"])[0] normal_attributes = attributes.keys dn, attributes = @group_class.search(:attributes => ["*", "+"])[0] operational_attributes = attributes.keys - normal_attributes operational_attribute = operational_attributes[0] group = @group_class.find(:first, :attributes => ["*", "+"]) operational_attribute_value = group[operational_attribute] assert_not_nil(operational_attribute_value) group.save! assert_equal(operational_attribute_value, group[operational_attribute]) end end def test_destroy_mixed_tree_by_instance make_ou("base") _entry_class = entry_class("ou=base") _ou_class = ou_class("ou=base") _dc_class = dc_class("ou=base") root1 = _ou_class.create("root1") _ou_class.create(:ou => "child1", :parent => root1) _ou_class.create(:ou => "child2", :parent => root1) _dc_class.create(:dc => "domain", :o => "domain", :parent => root1) _ou_class.create(:ou => "child3", :parent => root1) _ou_class.create("root2") assert_equal(["base", "root1", "child1", "child2", "domain", "child3", "root2"], _entry_class.find(:all).collect(&:id)) assert_raise(ActiveLdap::DeleteError) do root1.destroy_all end assert_equal(["base", "root1", "domain", "root2"], _entry_class.find(:all).collect(&:id)) end def test_delete_mixed_tree_by_instance make_ou("base") _entry_class = entry_class("ou=base") _ou_class = ou_class("ou=base") _dc_class = dc_class("ou=base") root1 = _ou_class.create("root1") _ou_class.create(:ou => "child1", :parent => root1) _ou_class.create(:ou => "child2", :parent => root1) _dc_class.create(:dc => "domain", :o => "domain", :parent => root1) _ou_class.create(:ou => "child3", :parent => root1) _ou_class.create("root2") assert_equal(["base", "root1", "child1", "child2", "domain", "child3", "root2"], _entry_class.find(:all).collect(&:id)) assert_raise(ActiveLdap::DeleteError) do root1.delete_all end assert_equal(["base", "root1", "domain", "root2"], _entry_class.find(:all).collect(&:id)) end def test_delete_tree make_ou("base") _ou_class = ou_class("ou=base") root1 = _ou_class.create("root1") _ou_class.create(:ou => "child1", :parent => root1) _ou_class.create(:ou => "child2", :parent => root1) _ou_class.create("root2") assert_equal(["base", "root1", "child1", "child2", "root2"], _ou_class.find(:all).collect(&:ou)) _ou_class.delete_all(:base => root1.dn) assert_equal(["base", "root2"], _ou_class.find(:all).collect(&:ou)) end def test_delete_mixed_tree make_ou("base") _ou_class = ou_class("ou=base") domain_class = Class.new(ActiveLdap::Base) domain_class.ldap_mapping :dn_attribute => "dc", :prefix => "", :classes => ['domain'] root1 = _ou_class.create("root1") child1 = _ou_class.create(:ou => "child1", :parent => root1) domain_class.create(:dc => "domain1", :parent => child1) _ou_class.create(:ou => "grandchild1", :parent => child1) child2 = _ou_class.create(:ou => "child2", :parent => root1) domain_class.create(:dc => "domain2", :parent => child2) _ou_class.create("root2") entry_class = Class.new(ActiveLdap::Base) entry_class.ldap_mapping :prefix => "ou=base", :classes => ["top"] entry_class.dn_attribute = nil assert_equal(["base", "root1", "child1", "domain1", "grandchild1", "child2", "domain2", "root2"], entry_class.find(:all).collect(&:id)) entry_class.delete_all(nil, :base => child2.dn) assert_equal(["base", "root1", "child1", "domain1", "grandchild1", "root2"], entry_class.find(:all).collect(&:id)) end def test_first make_temporary_user(:simple => true) do |user1,| make_temporary_user(:simple => true) do |user2,| assert_equal(user1, @user_class.find(:first)) assert_equal(user2, @user_class.find(:first, user2.cn)) end end end def test_last make_temporary_user(:simple => true) do |user1,| make_temporary_user(:simple => true) do |user2,| assert_equal(user2, @user_class.find(:last)) assert_equal(user1, @user_class.find(:last, user1.cn)) end end end def test_convenient_operation_methods make_temporary_user(:simple => true) do |user1,| make_temporary_user(:simple => true) do |user2,| assert_equal(user1, @user_class.first) assert_equal(user2, @user_class.last) assert_equal([user1, user2], @user_class.all) end end end def test_set_single_valued_attribute_uses_replace make_temporary_user(:simple => true) do |user,| assert_not_nil(user.homeDirectory) assert_not_equal("/home/foo", user.homeDirectory) user.homeDirectory = "/home/foo" assert_equal({ :modified => true, :entries => [ [ :replace, "homeDirectory", {"homeDirectory" => ["/home/foo"]}, ] ] }, detect_modify(user) {user.save}) assert_equal("/home/foo", user.homeDirectory) end end def test_set_attribute_uses_add_for_completely_new_value make_temporary_user(:simple => true) do |user,| assert_nil(user.description) user.description = "x" assert_equal({ :modified => true, :entries => [ [:add, "description", {"description" => ["x"]}], ], }, detect_modify(user) {user.save}) assert_equal("x", user.description) end end def test_set_attribute_uses_add_for_added_value make_temporary_user(:simple => true) do |user,| user.description = ["a", "b"] assert(user.save) user.description = ["a", "b", "c"] assert_equal({ :modified => true, :entries => [ [:add, "description", {"description" => ["c"]}], ], }, capture = detect_modify(user) {user.save}) assert_equal(["a", "b", "c"], user.description) end end def test_set_attribute_uses_delete_for_deleted_value make_temporary_user(:simple => true) do |user,| user.description = ["a", "b", "c"] assert(user.save) user.description = ["a", "c"] assert_equal({ :modified => true, :entries => [ [:delete, "description", {"description" => ["b"]}], ], }, detect_modify(user) {user.save}) assert_equal(["a", "c"], user.description) end end def test_set_attribute_uses_delete_for_unset_value make_temporary_user(:simple => true) do |user,| user.description = "x" assert(user.save) user.description = nil assert_equal({ :modified => true, :entries => [ [:delete, "description", {"description" => ["x"]}], ], }, detect_modify(user) {user.save}) assert_nil(user.description) end end def test_set_attributes_with_a_blank_value_in_values make_temporary_user(:simple => true) do |user,| user.attributes = {"description" => ["a", "b", ""]} assert(user.save) end end def test_set_attributes_with_a_blank_value make_temporary_user(:simple => true) do |user,| user.attributes = {"description" => [""]} assert(user.save) end end def test_create_invalid user = @user_class.create assert_not_predicate(user.errors, :empty?) end def test_id_with_invalid_dn_attribute_value user = @user_class.new("#") assert_equal("#", user.uid) assert_equal("#", user.id) end def test_non_string_dn_attribute_value user = @user_class.new("uidNumber=10110") user.uid = user.cn = user.sn = "test-user" user.gid_number = 10000 user.home_directory = "/home/test-user" assert_nothing_raised do user.save! end end def test_set_dn_with_unnormalized_dn_attribute make_temporary_user do |user,| assert_not_equal("ZZZ", user.cn) user.dn = "CN=ZZZ" assert_equal("ZZZ", user.cn) end end def test_destroy_with_empty_base_and_prefix_of_class make_temporary_user do |user,| base = user.class.base prefix = user.class.prefix begin user.class.base = "" user.class.prefix = "" user.base = base user.destroy ensure user.class.base = base user.class.prefix = prefix end end end def test_empty_base_of_class make_temporary_user do |user,| user.class.prefix = "" user.class.base = "" user.base = "dc=net" assert_equal("dc=net", user.base) end end def test_search_value_with_no_dn_attribute make_temporary_user do |user1,| make_temporary_user do |user2,| options = {:attribute => "seeAlso", :value => user2.dn} assert_equal([], user1.class.find(:all, options).collect(&:dn)) user1.see_also = user2.dn user1.save! assert_equal([user1.dn], user1.class.find(:all, options).collect(&:dn)) end end end def test_to_s make_temporary_group do |group| assert_equal(group.to_s, group.to_ldif) end end def test_to_ldif make_temporary_group do |group| assert_to_ldif(group) group.gidNumber += 1 group.description = ["Description", {"en" => "Description(en)"}] assert_to_ldif(group) end end def test_save_with_changes make_temporary_user do |user, password| cn = user.cn user.cn += "!!!" assert_equal({ :modified => true, :entries => [ [:replace, "cn", {"cn" => ["#{cn}!!!"]}], ], }, detect_modify(user) {user.save}) end end def test_save_without_changes make_temporary_user do |user, password| assert_equal({ :modified => false, :entries => [], }, detect_modify(user) {user.save}) end end def test_normalize_dn_attribute make_ou("Ous") ou_class = Class.new(ActiveLdap::Base) ou_class.ldap_mapping(:dn_attribute => "OU", :prefix => "ou=OUS", :classes => ["top", "organizationalUnit"]) ou_class.new("ou1").save! ou_class.new("ou2").save! ou1 = ou_class.find("ou1") assert_equal("ou1", ou1.ou) assert_equal("ou=ou1,#{ou_class.base}", ou1.dn) ou2 = ou_class.find("ou2") assert_equal("ou2", ou2.ou) assert_equal("ou=ou2,#{ou_class.base}", ou2.dn) end def test_excluded_classes mapping = {:classes => ["person"]} person_class = Class.new(@user_class) person_class.ldap_mapping(mapping) person_class.prefix = nil no_organizational_person_class = Class.new(@user_class) no_organizational_person_mapping = mapping.merge(:excluded_classes => ["organizationalPerson"]) no_organizational_person_class.ldap_mapping(no_organizational_person_mapping) no_organizational_person_class.prefix = nil no_simple_person_class = Class.new(@user_class) no_simple_person_mapping = mapping.merge(:excluded_classes => ['shadowAccount', 'inetOrgPerson', "organizationalPerson"]) no_simple_person_class.ldap_mapping(no_simple_person_mapping) no_simple_person_class.prefix = nil make_temporary_user do |user1,| make_temporary_user(:simple => true) do |user2,| assert_equal([user1.dn, user2.dn].sort, person_class.find(:all).collect(&:dn).sort) no_organizational_people = no_organizational_person_class.find(:all) assert_equal([user2.dn].sort, no_organizational_people.collect(&:dn).sort) assert_equal([user2.dn].sort, no_simple_person_class.find(:all).collect(&:dn).sort) end end end def test_new_with_dn cn = "XXX" dn = "cn=#{cn},#{@user_class.base}" user = @user_class.new(ActiveLdap::DN.parse(dn)) assert_equal(cn, user.cn) assert_equal(dn, user.dn) end def test_dn_attribute_per_instance_with_invalid_value user = @user_class.new assert_equal("uid", user.dn_attribute) user.dn = nil assert_equal("uid", user.dn_attribute) assert_nil(user.uid) user.dn = "" assert_equal("uid", user.dn_attribute) assert_nil(user.uid) end def test_dn_attribute_per_instance user = @user_class.new assert_equal("uid", user.dn_attribute) assert_nil(user.uid) user.dn = "cn=xxx" assert_equal("cn", user.dn_attribute) assert_nil(user.uid) assert_equal("xxx", user.cn) assert_equal("cn=xxx,#{@user_class.base}", user.dn) assert_equal("uid", @user_class.new.dn_attribute) user.dn = "ZZZ" assert_equal("cn", user.dn_attribute) assert_nil(user.uid) assert_equal("ZZZ", user.cn) assert_equal("cn=ZZZ,#{@user_class.base}", user.dn) user.dn = "uid=aaa" assert_equal("uid", user.dn_attribute) assert_equal("aaa", user.uid) assert_equal("ZZZ", user.cn) assert_equal("uid=aaa,#{@user_class.base}", user.dn) end def test_case_insensitive_nested_ou ou_class("ou=Users").new("Sub").save! make_temporary_user(:uid => "test-user,ou=SUB") do |user, password| sub_user_class = Class.new(@user_class) sub_user_class.ldap_mapping :prefix => "ou=sub" assert_equal(dn("uid=test-user,ou=sub,#{@user_class.base}"), sub_user_class.find(user.uid).dn) end end def test_nested_ou make_ou("units") units = ou_class("ou=units") units.new("one").save! units.new("two").save! units.new("three").save! ous = units.find(:all, :scope => :sub).collect {|unit| unit.ou} assert_equal(["one", "two", "three", "units"].sort, ous.sort) ous = units.find(:all, :scope => :base).collect {|unit| unit.ou} assert_equal(["units"].sort, ous.sort) ous = units.find(:all, :scope => :one).collect {|unit| unit.ou} assert_equal(["one", "two", "three"].sort, ous.sort) end def test_initialize_with_recommended_classes mapping = { :dn_attribute => "cn", :prefix => "", :scope => :one, :classes => ["person"], } person_class = Class.new(ActiveLdap::Base) person_class.ldap_mapping mapping person_with_uid_class = Class.new(ActiveLdap::Base) person_with_uid_mapping = mapping.merge(:recommended_classes => ["uidObject"]) person_with_uid_class.ldap_mapping person_with_uid_mapping name = "sample" name_with_uid = "sample-with-uid" uid = "1000" person = person_class.new(name) person.sn = name assert(person.save) assert_equal([name, name], [person.cn, person.sn]) person_with_uid = person_with_uid_class.new(name_with_uid) person_with_uid.sn = name_with_uid assert(!person_with_uid.save) person_with_uid.uid = uid assert(person_with_uid.save) assert_equal([name_with_uid, name_with_uid], [person_with_uid.cn, person_with_uid.sn]) assert_equal(uid, person_with_uid.uid) assert_equal([person.dn, person_with_uid.dn], person_class.search.collect {|dn, attrs| dn}) person_class.required_classes += ["uidObject"] assert_equal([person_with_uid.dn], person_class.search.collect {|dn, attrs| dn}) assert_equal([person.dn, person_with_uid.dn], person_with_uid_class.search.collect {|dn, attrs| dn}) end def test_search_with_object_class ou_class = Class.new(ActiveLdap::Base) ou_class.ldap_mapping :dn_attribute => "ou", :prefix => "", :scope => :one, :classes => ["organizationalUnit"] name = "sample" ou = ou_class.new(name) assert(ou.save) assert_equal(name, ou.ou) assert_equal([ou.dn], ou_class.search(:value => name).collect {|dn, attrs| dn}) ou_class.required_classes += ["organization"] assert_equal([], ou_class.search(:value => name).collect {|dn, attrs| dn}) end def test_search_with_attributes_without_object_class make_temporary_user do |user, password| entries = @user_class.search(:filter => "#{user.dn_attribute}=#{user.id}", :attributes => ["uidNumber"]) assert_equal([[user.dn, {"uidNumber" => [user.uid_number.to_s]}]], entries) end end def test_new_without_argument user = @user_class.new assert_equal(@user_class_classes, user.classes) assert(user.respond_to?(:cn)) end def test_new_with_invalid_argument @user_class.new assert_raises(ArgumentError) do @user_class.new(100) end end def test_loose_dn make_temporary_user do |user,| assert(user.class.exists?(user.dn.to_s)) assert(user.class.exists?(user.dn.to_s.gsub(/\b,/, " , "))) assert(user.class.exists?(user.dn.to_s.gsub(/\b=/, " = "))) end end def test_new_without_class no_class_class = Class.new(ActiveLdap::Base) no_class_class.ldap_mapping :dn_attribute => "dc", :prefix => "", :classes => [] assert_raises(ActiveLdap::UnknownAttribute) do no_class_class.new("xxx") end end def test_save_for_dNSDomain domain_class = Class.new(ActiveLdap::Base) domain_class.ldap_mapping :dn_attribute => "dc", :prefix => "", :classes => ['top', 'dcObject', 'dNSDomain'] name = "ftp" a_record = "192.168.1.1" domain = domain_class.new('ftp') domain.a_record = a_record assert(domain.save) assert_equal(a_record, domain.a_record) assert_equal(a_record, domain_class.find(name).a_record) ensure domain_class.delete(name) if domain_class.exists?(name) end def test_dn_by_index_getter make_temporary_user do |user,| assert_equal(user.dn, user["dn"]) end end def test_create_multiple ensure_delete_user("temp-user1") do |uid1,| ensure_delete_user("temp-user2") do |uid2,| attributes = { :uid => uid2, :sn => uid2, :cn => uid2, :uid_number => "1000", :gid_number => "1000", :home_directory => "/home/#{uid2}", } user1, user2 = @user_class.create([{:uid => uid1}, attributes]) assert(!user1.errors.empty?) assert(!@user_class.exists?(uid1)) assert_equal([], user2.errors.to_a) assert(@user_class.exists?(uid2)) attributes.each do |key, value| value = value.to_i if [:uid_number, :gid_number].include?(key) assert_equal(value, user2[key]) end end end end def test_create ensure_delete_user("temp-user") do |uid,| user = @user_class.create(:uid => uid) assert(!user.errors.empty?) assert(!@user_class.exists?(uid)) attributes = { :uid => uid, :sn => uid, :cn => uid, :uid_number => "1000", :gid_number => "1000", :home_directory => "/home/#{uid}", } user = @user_class.create(attributes) assert_equal([], user.errors.to_a) assert(@user_class.exists?(uid)) attributes.each do |key, value| value = value.to_i if [:uid_number, :gid_number].include?(key) assert_equal(value, user[key]) end end end class TestInstantiate < self class Person < ActiveLdap::Base ldap_mapping dn_attribute: "cn", prefix: "ou=People", scope: :one, classes: ["top", "person"] end class OrganizationalPerson < Person ldap_mapping dn_attribute: "cn", prefix: "", classes: ["top", "person", "organizationalPerson"] end class ResidentialPerson < Person ldap_mapping dn_attribute: "cn", prefix: "", classes: ["top", "person", "residentialPerson"] end def test_sub_class make_ou("People") residential_person = ResidentialPerson.new(cn: "John Doe", sn: "Doe", street: "123 Main Street", l: "Anytown") residential_person.save! organizational_person = OrganizationalPerson.new(cn: "Jane Smith", sn: "Smith", title: "General Manager") organizational_person.save! people = Person.all assert_equal([ResidentialPerson, OrganizationalPerson], people.collect(&:class)) end end def test_reload_of_not_exists_entry make_temporary_user do |user,| assert_nothing_raised do user.reload end user.destroy assert_raises(ActiveLdap::EntryNotFound) do user.reload end end end def test_reload_and_new_entry make_temporary_user do |user1,| user2 = @user_class.new(user1.uid) assert_equal(user1.attributes["uid"], user2.attributes["uid"]) assert_not_equal(user1.attributes["objectClass"], @user_class.required_classes) assert_equal(@user_class.required_classes, user2.attributes["objectClass"]) assert_not_equal(user1.attributes["objectClass"], user2.attributes["objectClass"]) assert(user2.exists?) assert(user2.new_entry?) user2.reload assert(user2.exists?) assert(!user2.new_entry?) assert_equal(user1.attributes, user2.attributes) end end def test_exists_for_instance make_temporary_user do |user,| assert(user.exists?) assert(!user.new_entry?) new_user = @user_class.new(user.uid) assert(new_user.exists?) assert(new_user.new_entry?) user.destroy assert(!user.exists?) assert(user.new_entry?) assert(!new_user.exists?) assert(new_user.new_entry?) end end def test_exists_without_required_object_class make_temporary_user do |user,| @user_class.required_classes -= ["posixAccount"] user.remove_class("posixAccount") assert(user.save) assert(@user_class.exists?(user.dn)) @user_class.required_classes += ["posixAccount"] assert(!@user_class.exists?(user.dn)) assert_raises(ActiveLdap::EntryNotFound) do @user_class.find(user.dn) end end end def test_find_dns_without_required_object_class make_temporary_user do |user1,| make_temporary_user do |user2,| make_temporary_user do |user3,| @user_class.required_classes -= ["posixAccount"] user1.remove_class("posixAccount") assert(user1.save) @user_class.required_classes += ["posixAccount"] assert_raises(ActiveLdap::EntryNotFound) do @user_class.find(user1.dn, user2.dn, user3.dn) end assert_equal([user2.dn, user3.dn], @user_class.find(user2.dn, user3.dn).collect {|u| u.dn}) end end end end def test_reload make_temporary_user do |user1,| user2 = @user_class.find(user1.uid) assert_equal(user1.attributes, user2.attributes) user1.cn = "new #{user1.cn}" assert_not_equal(user1.attributes, user2.attributes) assert_equal(user1.attributes.reject {|k, v| k == "cn"}, user2.attributes.reject {|k, v| k == "cn"}) user2.reload assert_not_equal(user1.attributes, user2.attributes) assert_equal(user1.attributes.reject {|k, v| k == "cn"}, user2.attributes.reject {|k, v| k == "cn"}) assert(user1.save) assert_not_equal(user1.attributes, user2.attributes) assert_equal(user1.attributes.reject {|k, v| k == "cn"}, user2.attributes.reject {|k, v| k == "cn"}) user2.reload assert_equal(user1.cn, user2.cn) assert_equal(user1.attributes.reject {|k, v| k == "cn"}, user2.attributes.reject {|k, v| k == "cn"}) end end def test_inherit_base sub_user_class = Class.new(@user_class) sub_user_class.ldap_mapping :prefix => "ou=Sub" assert_equal("ou=Sub,#{@user_class.base}", sub_user_class.base) sub_user_class.send(:include, Module.new) assert_equal("ou=Sub,#{@user_class.base}", sub_user_class.base) sub_sub_user_class = Class.new(sub_user_class) sub_sub_user_class.ldap_mapping :prefix => "ou=SubSub" assert_equal("ou=SubSub,#{sub_user_class.base}", sub_sub_user_class.base) sub_sub_user_class.send(:include, Module.new) assert_equal("ou=SubSub,#{sub_user_class.base}", sub_sub_user_class.base) end def test_compare make_temporary_user do |user1,| make_temporary_user do |user2,| make_temporary_user do |user3,| make_temporary_user do |user4,| actual = ([user1, user2, user3] & [user1, user4]) assert_equal([user1].collect {|user| user.id}, actual.collect {|user| user.id}) end end end end end def test_ldap_mapping_symbol_dn_attribute ou_class = Class.new(ActiveLdap::Base) ou_class.ldap_mapping(:dn_attribute => :ou, :prefix => "", :classes => ["top", "organizationalUnit"]) assert_equal(["ou=Groups,#{current_configuration['base']}", "ou=Users,#{current_configuration['base']}"], ou_class.find(:all).collect(&:dn).collect(&:to_s).sort) end def test_ldap_mapping_validation ou_class = Class.new(ActiveLdap::Base) assert_raises(ArgumentError) do ou_class.ldap_mapping :dnattr => "ou" end assert_nothing_raised do ou_class.ldap_mapping :dn_attribute => "ou", :prefix => "", :classes => ["top", "organizationalUnit"] end end class TestToXML < self def test_root ou = ou_class.new("Sample") assert_equal(<<-EOX, ou.to_xml(:root => "ou")) #{ou.dn} organizationalUnit top Sample EOX end def test_default ou = ou_class.new("Sample") assert_equal(<<-EOX, ou.to_xml) #{ou.dn} organizationalUnit top Sample EOX end def test_complex make_temporary_user do |user, password| xml = normalize_attributes_order(user.to_xml(:root => "user")) assert_equal(<<-EOX, xml) #{user.dn} #{user.cn} #{user.gid_number} #{user.home_directory} #{base64(jpeg_photo)} inetOrgPerson organizationalPerson person posixAccount shadowAccount #{user.sn} #{user.uid} #{user.uid_number} #{base64(certificate)} #{user.user_password} EOX end end def test_except ou = ou_class.new("Sample") except = [:objectClass] assert_equal(<<-EOX, ou.to_xml(:root => "sample", :except => except)) #{ou.dn} Sample EOX end def test_except_dn ou = ou_class.new("Sample") except = [:dn, :object_class] assert_equal(<<-EOX, ou.to_xml(:root => "sample", :except => except)) Sample EOX end def test_only ou = ou_class.new("Sample") only = [:objectClass] assert_equal(<<-EOX, ou.to_xml(:root => "sample", :only => only)) organizationalUnit top EOX end def test_only_dn ou = ou_class.new("Sample") only = [:dn, :object_class] assert_equal(<<-EOX, ou.to_xml(:root => "sample", :only => only)) #{ou.dn} organizationalUnit top EOX end def test_escape make_temporary_user do |user, password| sn = user.sn user.sn = "<#{sn}>" except = [:jpeg_photo, :user_certificate] assert_equal(<<-EOX, user.to_xml(:root => "user", :except => except)) #{user.dn} #{user.cn} #{user.gid_number} #{user.home_directory} inetOrgPerson organizationalPerson person posixAccount shadowAccount <#{sn}> #{user.uid} #{user.uid_number} #{user.user_password} EOX end end def test_type_ldif make_temporary_user do |user, password| sn = user.sn user.sn = "<#{sn}>" except = [:jpeg_photo, :user_certificate] options = {:root => "user", :except => except, :type => :ldif} assert_equal(<<-EOX, user.to_xml(options)) #{user.dn} #{user.cn} #{user.gid_number} #{user.home_directory} inetOrgPerson organizationalPerson person posixAccount shadowAccount <#{sn}> #{user.uid} #{user.uid_number} #{user.user_password} EOX end end def test_nil ou = ou_class.new("Sample") ou.description = [nil] assert_equal(<<-EOX, ou.to_xml(:root => "sample")) #{ou.dn} organizationalUnit top Sample EOX end def test_single_value make_temporary_user do |user, password| only = [:dn, :uidNumber] assert_equal(<<-EOX, user.to_xml(:root => "user", :only => only)) #{user.dn} #{user.uid_number} EOX end end def test_single_value_nil make_temporary_user do |user, password| only = [:dn, :uidNumber] user.uid_number = nil assert_equal(<<-EOX, user.to_xml(:root => "user", :only => only)) #{user.dn} EOX end end end def test_save make_temporary_user do |user, password| user.sn = nil assert(!user.save) assert_raises(ActiveLdap::EntryInvalid) do user.save! end user.sn = "Surname" assert(user.save) user.sn = "Surname2" assert_nothing_raised {user.save!} end end def test_have_attribute? make_temporary_user do |user, password| assert_true(user.have_attribute?(:cn)) assert_true(user.have_attribute?(:commonName)) assert_true(user.have_attribute?(:common_name)) assert_true(user.have_attribute?(:commonname)) assert_true(user.have_attribute?(:COMMONNAME)) assert_false(user.have_attribute?(:unknown_attribute)) end end def test_attribute_present? make_temporary_user do |user, password| assert(user.attribute_present?(:sn)) user.sn = nil assert(!user.attribute_present?(:sn)) user.sn = "Surname" assert(user.attribute_present?(:sn)) user.sn = [nil] assert(!user.attribute_present?(:sn)) end end def test_attribute_present_with_unknown_attribute make_temporary_user do |user, password| assert(!user.attribute_present?(:unknown_attribute)) end end def test_update_all make_temporary_user do |user, password| make_temporary_user do |user2, password2| user2_cn = user2.cn new_cn = "New #{user.cn}" @user_class.update_all({:cn => new_cn}, user.uid) assert_equal(new_cn, @user_class.find(user.uid).cn) assert_equal(user2_cn, @user_class.find(user2.uid).cn) new_sn = "New SN" @user_class.update_all({:sn => [new_sn]}) assert_equal(new_sn, @user_class.find(user.uid).sn) assert_equal(new_sn, @user_class.find(user2.uid).sn) new_sn2 = "New SN2" @user_class.update_all({:sn => [new_sn2]}, user2.uid) assert_equal(new_sn, @user_class.find(user.uid).sn) assert_equal(new_sn2, @user_class.find(user2.uid).sn) end end end def test_update make_temporary_user do |user, password| new_cn = "New #{user.cn}" new_user = @user_class.update(user.dn, {:cn => new_cn}) assert_equal(new_cn, new_user.cn) make_temporary_user do |user2, password2| new_sns = ["New SN1", "New SN2"] new_cn2 = "New #{user2.cn}" new_user, new_user2 = @user_class.update([user.dn, user2.dn], [{:sn => new_sns[0]}, {:sn => new_sns[1], :cn => new_cn2}]) assert_equal(new_sns, [new_user.sn, new_user2.sn]) assert_equal(new_cn2, new_user2.cn) end end end def test_to_key uid = "bob" new_user = @user_class.new assert_equal(nil, new_user.to_key) new_user.uid = uid assert_equal([new_user.dn], new_user.to_key) end private def detect_modify(object) modify_called = nil entries = nil singleton_class = class << object; self; end singleton_class.send(:define_method, :modify_entry) do |*args| dn, attributes, options = args options ||= {} modify_detector = Object.new modify_detector.instance_variable_set("@called", false) modify_detector.instance_variable_set("@entries", []) def modify_detector.modify(dn, entries, options) @called = true @entries = entries end options[:connection] = modify_detector result = super(dn, attributes, options) modify_called = modify_detector.instance_variable_get("@called") entries = modify_detector.instance_variable_get("@entries") result end yield { :modified => modify_called, :entries => entries, } end def assert_to_ldif(entry) records = ActiveLdap::LDIF.parse(entry.to_ldif).records parsed_entries = records.collect do |record| entry.class.send(:instantiate, [record.dn, record.attributes]) end assert_equal([entry], parsed_entries) end def base64(string) [string].pack("m").gsub(/\n/u, "") end def normalize_attributes_order(xml) xml.gsub(/<(\S+) (.+?)(\/?)>/) do |matched| name = $1 attributes = $2 close_mark = $3 attributes = attributes.scan(/(\S+)="(.+?)"/) normalized_attributes = attributes.sort_by do |key, value| key end.collect do |key, value| "#{key}=\"#{value}\"" end.join(' ') "<#{name} #{normalized_attributes}#{close_mark}>" end end end activeldap-5.2.4/test/test_callback.rb0000644000004100000410000000223313464071751017775 0ustar www-datawww-datarequire 'al-test-utils' class TestCallback < Test::Unit::TestCase include AlTestUtils priority :must def test_new initialized_entries = [] @group_class.module_eval do after_initialize do initialized_entries << self end end assert_equal([], initialized_entries) new_group = @group_class.new(:cn => "new-cn") assert_equal([new_group.cn].sort, initialized_entries.collect {|g| g.cn}.sort) end priority :normal def test_find make_temporary_group do |group| found_entries = [] initialized_entries = [] @group_class.module_eval do prepend ActiveLdap::Callbacks::CallbackedInstantiatable after_find do found_entries << self end after_initialize do initialized_entries << self end end assert_equal([], found_entries) assert_equal([], initialized_entries) found_group = @group_class.find(group.dn) assert_equal([found_group.cn].sort, found_entries.collect {|g| g.cn}.sort) assert_equal([found_group.cn].sort, initialized_entries.collect {|g| g.cn}.sort) end end end activeldap-5.2.4/test/test_useradd.rb0000644000004100000410000000307713464071751017677 0ustar www-datawww-datarequire 'al-test-utils' class TestUseradd < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "useradd") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_exist_user make_temporary_user do |user, password| assert(@user_class.exists?(user.uid)) assert_equal([false, "User #{user.uid} already exists.\n"], run_command(user.uid, user.cn, user.uid_number)) assert(@user_class.exists?(user.uid)) end end def test_add_user ensure_delete_user("test-user") do |uid,| assert_useradd_successfully(uid, uid, 10000) end end private def assert_useradd_successfully(name, cn, uid, *args, &block) _wrap_assertion do assert(!@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([true, ""], run_command(*args, &block)) assert(@user_class.exists?(name)) user = @user_class.find(name) assert_equal(name, user.uid) assert_equal(cn, user.cn) assert_equal(uid.to_i, user.uid_number) assert_equal(uid.to_i, user.gid_number) assert_equal(uid.to_s, user.uid_number_before_type_cast) assert_equal(uid.to_s, user.gid_number_before_type_cast) end end def assert_useradd_failed(name, cn, uid, message, *args, &block) _wrap_assertion do assert(!@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([false, message], run_command(*args, &block)) assert(!@user_class.exists?(name)) end end end activeldap-5.2.4/test/test_base_per_instance.rb0000644000004100000410000000340713464071751021711 0ustar www-datawww-datarequire 'al-test-utils' class TestBasePerInstance < Test::Unit::TestCase include AlTestUtils def setup super ou_class("ou=Users").new("Sub").save! end priority :must def test_set_base guest = @user_class.new("guest") guest.base = "ou=Sub" assert_equal("uid=guest,ou=Sub,#{@user_class.base}", guest.dn) end priority :normal def test_dn_is_base entry_class = Class.new(ActiveLdap::Base) entry_class.ldap_mapping :prefix => "", :classes => ["top"], :scope => :sub entry_class.dn_attribute = nil entry = entry_class.root assert_equal(entry_class.base, entry.dn) assert_equal(entry_class.base, entry.base) end def test_loose_dn user = @user_class.new("test-user , ou = Sub") assert_equal("uid=test-user,ou=Sub,#{@user_class.base}", user.dn) user = @user_class.new("test-user , ou = Sub, #{@user_class.base}") assert_equal("uid=test-user,ou=Sub,#{@user_class.base}", user.dn) end def test_exists? make_temporary_user(:uid => "test-user,ou=Sub") do |user, password| assert(@user_class.exists?(user.uid)) assert(@user_class.exists?("uid=#{user.uid}")) assert(@user_class.exists?(user.dn)) assert(@user_class.exists?("test-user,ou=Sub")) assert(@user_class.exists?("uid=test-user,ou=Sub")) end end def test_add make_temporary_user(:uid => "test-user,ou=Sub") do |user, password| assert_equal("uid=test-user,ou=Sub,#{@user_class.base}", user.dn) assert_equal("test-user", user.uid) end make_temporary_user(:uid => "uid=test-user,ou=Sub") do |user, password| assert_equal("uid=test-user,ou=Sub,#{@user_class.base}", user.dn) assert_equal("test-user", user.uid) end end end activeldap-5.2.4/test/test_lpasswd.rb0000644000004100000410000000433113464071751017717 0ustar www-datawww-datarequire 'al-test-utils' class TestLPasswd < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "lpasswd") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_user ensure_delete_user("test-user") do |uid,| assert(!@user_class.exists?(uid)) assert_equal([false, "User #{uid} doesn't exist.\n"], run_command(uid)) assert(!@user_class.exists?(uid)) end end def test_change_password make_temporary_user do |user, password| new_password = "new#{password}" assert_lpasswd_successfully(user.uid, password, new_password) end end def test_password_mismatch make_temporary_user do |user, password| message = "[#{user.dn}] Password: \n" * 2 message = "#{message}Password mismatch!\n" * 3 assert_lpasswd_failed(user.id, password, message) do |input, output| 3.times do output.puts("new#{password}1") output.puts("new#{password}2") output.flush end end end end private def assert_lpasswd_successfully(name, current, new, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) assert_send([ActiveLdap::UserPassword, :valid?, current, @user_class.find(name).user_password]) args.concat([name]) block ||= Proc.new do |input, output| output.puts(new) output.puts(new) output.flush end assert_equal([true, "[#{@user_class.find(name).dn}] Password: \n" * 2], run_command(*args, &block)) assert_send([ActiveLdap::UserPassword, :valid?, new, @user_class.find(name).user_password]) end end def assert_lpasswd_failed(name, current, message, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) assert_send([ActiveLdap::UserPassword, :valid?, current, @user_class.find(name).user_password]) args.concat([name]) assert_equal([false, message], run_command(*args, &block)) assert_send([ActiveLdap::UserPassword, :valid?, current, @user_class.find(name).user_password]) end end end activeldap-5.2.4/test/test_entry_attribute.rb0000644000004100000410000000120213464071751021460 0ustar www-datawww-data# -*- coding: utf-8 -*- require "al-test-utils" class TestEntryAttribute < Test::Unit::TestCase include AlTestUtils class TestExist < self priority :must def test_existence schema = ActiveLdap::Base.connection.schema object_classes = ["posixAccount"] entry_attribute = ActiveLdap::EntryAttribute.new(schema, object_classes) assert_true(entry_attribute.exist?("cn")) end def test_non_existence schema = nil object_classes = [] entry_attribute = ActiveLdap::EntryAttribute.new(schema, object_classes) assert_false(entry_attribute.exist?("nonExistence")) end end end activeldap-5.2.4/test/test_connection_per_dn.rb0000644000004100000410000000715713464071751021741 0ustar www-datawww-datarequire 'al-test-utils' class TestConnectionPerDN < Test::Unit::TestCase include AlTestUtils priority :must def test_bind_with_empty_password make_temporary_user do |user, password| assert_equal(user.class.connection, user.connection) assert_raises(ActiveLdap::AuthenticationError) do user.bind("", :try_sasl => false) end assert_equal(user.class.connection, user.connection) assert_nothing_raised do user.bind("", :try_sasl => false, :allow_anonymous => true) end assert_not_equal(user.class.connection, user.connection) end end priority :normal def test_rebind_with_invalid_password make_temporary_user do |user, password| assert_equal(user.class.connection, user.connection) assert_nothing_raised do user.bind(password) end assert_not_equal(user.class.connection, user.connection) assert_raises(ActiveLdap::AuthenticationError) do user.bind(password + "-WRONG", :try_sasl => false) end end end def test_bind make_temporary_user do |user, password| assert_equal(user.class.connection, user.connection) assert_raises(ActiveLdap::AuthenticationError) do user.bind(:bind_dn => nil, :try_sasl => false, :allow_anonymous => false, :retry_limit => 0) end assert_equal(user.class.connection, user.connection) assert_nothing_raised do user.bind(:bind_dn => nil, :try_sasl => false, :allow_anonymous => true) end assert_not_equal(user.class.connection, user.connection) assert_equal(user.connection, user.class.find(user.dn).connection) begin assert_equal(user.connection, user.find(user.dn).connection) rescue ActiveLdap::EntryNotFound omit("requires permission for searching by 'uid' to anonymous user.") end end end def test_find make_temporary_user do |user, password| make_temporary_user do |user2, password2| user.bind(password) assert_not_equal(user.class.connection, user.connection) found_user2 = user.find(user2.dn) assert_not_equal(user2.connection, found_user2.connection) assert_equal(user.connection, found_user2.connection) assert_equal(found_user2.class.connection, found_user2.class.find(found_user2.dn).connection) found_user2.bind(password2) assert_not_equal(user.connection, found_user2.connection) assert_equal(user2.connection, found_user2.connection) end end end def test_associations make_temporary_user do |user, password| make_temporary_group do |group1| make_temporary_group do |group2| user.groups = [group1] assert_equal(group1.connection, user.connection) user.bind(password, :try_sasl => false) assert_not_equal(user.class.connection, user.connection) assert_not_equal(group1.connection, user.connection) assert_equal(user.groups[0].connection, user.connection) assert_raise(ActiveLdap::OperationNotPermitted) do user.groups << group2 end assert_equal([group1.cn], user.groups.collect(&:cn)) assert_not_equal(group1.connection, user.connection) assert_equal(user.groups[0].connection, user.connection) found_user = user.class.find(user.dn) assert_equal(user.connection, found_user.connection) assert_equal(found_user.connection, found_user.groups[0].connection) end end end end end activeldap-5.2.4/test/test_schema.rb0000644000004100000410000006250113464071751017505 0ustar www-datawww-datarequire 'al-test-utils' class TestSchema < Test::Unit::TestCase priority :must def test_directory_operation attributes_schema = "( 2.5.18.1 NAME 'createTimestamp' " + "DESC 'RFC4512: time which ob ject was created' " + "EQUALITY generalizedTimeMatch " + "ORDERING generalizedTimeOrderingMatch " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 " + "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )" assert_attribute_type({ :read_only => true, :single_value => true, :binary => false, :binary_required => false, :directory_operation => true, :syntax => "1.3.6.1.4.1.1466.115.121.1.24", :syntax_description => nil, }, "createTimestamp", [attributes_schema]) end priority :normal def test_dit_content_rule object_class_schema = "( 2.5.6.6 NAME 'person' DESC " + "'RFC2256: a person' SUP top STRUCTURAL MUST sn " + "MAY ( userPassword $ telephoneNumber ) )" dit_content_rule_schema = "( 2.5.6.6 NAME 'person' MUST cn " + "MAY ( seeAlso $ description ) )" attributes_schema = [ "( 2.5.4.3 NAME 'cn' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 2.5.4.4 NAME 'sn' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 2.5.4.35 NAME 'userPassword' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' )", "( 2.5.4.20 NAME 'telephoneNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 2.5.4.34 NAME 'seeAlso' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", "( 2.5.4.13 NAME 'description' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", ] entry = { "objectClasses" => [object_class_schema], "dITContentRules" => [dit_content_rule_schema], "attributeTypes" => attributes_schema, } schema = ActiveLdap::Schema.new(entry) object_class = schema.object_class("person") assert_equal({ :must => ["sn", "cn"], :may => ["userPassword", "telephoneNumber", "seeAlso", "description"], }, { :must => object_class.must.collect(&:name), :may => object_class.may.collect(&:name), }) end def test_oid_list_with_just_only_one_oid ou_schema = "( 2.5.6.5 NAME 'organizationalUnit' SUP top STRUCTURAL MUST " + "(ou ) MAY (c $ l $ st $ street $ searchGuide $ businessCategory $ " + "postalAddress $ postalCode $ postOfficeBox $ " + "physicalDeliveryOfficeName $ telephoneNumber $ telexNumber $ " + "teletexTerminalIdentifier $ facsimileTelephoneNumber $ x121Address $ " + "internationalISDNNumber $ registeredAddress $ destinationIndicator $ " + "preferredDeliveryMethod $ seeAlso $ userPassword $ co $ countryCode $ " + "desktopProfile $ defaultGroup $ managedBy $ uPNSuffixes $ gPLink $ " + "gPOptions $ msCOM-UserPartitionSetLink $ thumbnailLogo ) ) " expect = { :name => ["organizationalUnit"], :sup => ["top"], :structural => ["TRUE"], :must => %w(ou), :may => %w(c l st street searchGuide businessCategory postalAddress postalCode postOfficeBox physicalDeliveryOfficeName telephoneNumber telexNumber teletexTerminalIdentifier facsimileTelephoneNumber x121Address internationalISDNNumber registeredAddress destinationIndicator preferredDeliveryMethod seeAlso userPassword co countryCode desktopProfile defaultGroup managedBy uPNSuffixes gPLink gPOptions msCOM-UserPartitionSetLink thumbnailLogo), } assert_schema(expect, "2.5.6.5", ou_schema) assert_schema(expect, "organizationalUnit", ou_schema) end def test_normalize_attribute_value entry = { "attributeTypes" => [ "( 0.9.2342.19200300.100.1.25 NAME ( 'dc' 'domainComponent' ) DESC " + "'RFC1274/2247: domain component' EQUALITY caseIgnoreIA5Match SUBSTR " + "caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 " + "SINGLE-VALUE )", ], "ldapSyntaxes" => [ "( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", ], } schema = ActiveLdap::Schema.new(entry) dc = schema.attribute("dc") assert_equal(["com"], dc.normalize_value("com")) assert_equal(["com"], dc.normalize_value(["com"])) assert_raise(ActiveLdap::AttributeValueInvalid) do dc.normalize_value(["com", "co.jp"]) end assert_equal([{"lang-en" => ["com"]}, {"lang-ja" => ["co.jp"]}], dc.normalize_value([{"lang-en" => "com"}, {"lang-ja" => "co.jp"}])) end def test_syntax_validation entry = { "attributeTypes" => [ "( 2.5.4.34 NAME 'seeAlso' DESC 'RFC2256: DN of related object'" + "SUP distinguishedName )", "( 2.5.4.49 NAME 'distinguishedName' DESC 'RFC2256: common " + "supertype of DN attributes' EQUALITY distinguishedNameMatch "+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", ], "ldapSyntaxes" => [ "( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )", ], } schema = ActiveLdap::Schema.new(entry) see_also = schema.attribute("seeAlso") assert(see_also.valid?("cn=test,dc=example,dc=com")) assert(!see_also.valid?("test")) end def test_super_class? group = 'objectClasses' entry = { group => [ "( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP " + "top STRUCTURAL MUST ( sn $ cn ) MAY ( userPassword $ " + "telephoneNumber $ seeAlso $ description ) )", "( 2.5.6.7 NAME 'organizationalPerson' DESC 'RFC2256: " + "an organizational person' SUP person STRUCTURAL MAY ( " + "title $ x121Address $ registeredAddress $ " + "destinationIndicator $ preferredDeliveryMethod $ " + "telexNumber $ teletexTerminalIdentifier $ telephoneNumber " + "$ internationaliSDNNumber $ facsimileTelephoneNumber $ " + "street $ postOfficeBox $ postalCode $ postalAddress $ " + "physicalDeliveryOfficeName $ ou $ st $ l ) )", "( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC " + "'RFC2798: Internet Organizational Person' SUP " + "organizationalPerson STRUCTURAL MAY ( audio $ " + "businessCategory $ carLicense $ departmentNumber $ " + "displayName $ employeeNumber $ employeeType $ givenName " + "$ homePhone $ homePostalAddress $ initials $ jpegPhoto " + "$ labeledURI $ mail $ manager $ mobile $ o $ pager $ " + "photo $ roomNumber $ secretary $ uid $ userCertificate $ " + "x500UniqueIdentifier $ preferredLanguage $ " + "userSMIMECertificate $ userPKCS12 ) )", ] } schema = ActiveLdap::Schema.new(entry) person = schema.object_class('person') organizational_person = schema.object_class("organizationalPerson") inet_org_person = schema.object_class("inetOrgPerson") assert_equal([false, false, false], [person.super_class?(person), person.super_class?(organizational_person), person.super_class?(inet_org_person)]) assert_equal([true, false, false], [organizational_person.super_class?(person), organizational_person.super_class?(organizational_person), organizational_person.super_class?(inet_org_person)]) assert_equal([true, true, false], [inet_org_person.super_class?(person), inet_org_person.super_class?(organizational_person), inet_org_person.super_class?(inet_org_person)]) end def test_duplicate_schema sasNMASProductOptions_schema = "( 2.16.840.1.113719.1.39.42.1.0.38 NAME 'sasNMASProductOptions' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} SINGLE-VALUE " + "X-NDS_PUBLIC_READ '1' )" rADIUSActiveConnections_schema = "( 2.16.840.1.113719.1.39.42.1.0.38 NAME 'rADIUSActiveConnections' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64512} X-NDS_NAME " + "'RADIUS:ActiveConnections' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' )" sasNMASProductOptions = 'sasNMASProductOptions' rADIUSActiveConnections = 'rADIUSActiveConnections' sasNMASProductOptions_aliases = [sasNMASProductOptions, []] rADIUSActiveConnections_aliases = [rADIUSActiveConnections, []] sas_radius_aliases = [sasNMASProductOptions, [rADIUSActiveConnections]] radius_sas_aliases = [rADIUSActiveConnections, [sasNMASProductOptions]] assert_attribute_aliases([sasNMASProductOptions_aliases], [sasNMASProductOptions], [sasNMASProductOptions_schema], false) assert_attribute_aliases([rADIUSActiveConnections_aliases], [rADIUSActiveConnections], [rADIUSActiveConnections_schema], false) assert_attribute_aliases([sasNMASProductOptions_aliases, sas_radius_aliases], [sasNMASProductOptions, rADIUSActiveConnections], [sasNMASProductOptions_schema, rADIUSActiveConnections_schema], false) assert_attribute_aliases([rADIUSActiveConnections_aliases, radius_sas_aliases], [rADIUSActiveConnections, sasNMASProductOptions], [rADIUSActiveConnections_schema, sasNMASProductOptions_schema], false) assert_attribute_aliases([sas_radius_aliases, sas_radius_aliases], [rADIUSActiveConnections, sasNMASProductOptions], [sasNMASProductOptions_schema, rADIUSActiveConnections_schema], false) assert_attribute_aliases([radius_sas_aliases, radius_sas_aliases], [sasNMASProductOptions, rADIUSActiveConnections], [rADIUSActiveConnections_schema, sasNMASProductOptions_schema], false) assert_attribute_aliases([sas_radius_aliases, sas_radius_aliases], [sasNMASProductOptions, rADIUSActiveConnections], [sasNMASProductOptions_schema, rADIUSActiveConnections_schema], true) assert_attribute_aliases([radius_sas_aliases, radius_sas_aliases], [rADIUSActiveConnections, sasNMASProductOptions], [rADIUSActiveConnections_schema, sasNMASProductOptions_schema], true) end def test_empty_schema assert_make_schema_with_empty_entries(nil) assert_make_schema_with_empty_entries({}) assert_make_schema_with_empty_entries({"someValues" => ["aValue"]}) end def test_empty_schema_value schema = ActiveLdap::Schema.new({"attributeTypes" => nil}) assert_equal([], schema["attributeTypes", "cn", "DESC"]) end def test_attribute_name_with_under_score top_schema = "( 2.5.6.0 NAME 'Top' STRUCTURAL MUST objectClass MAY ( " + "cAPublicKey $ cAPrivateKey $ certificateValidityInterval $ " + "authorityRevocation $ lastReferencedTime $ " + "equivalentToMe $ ACL $ backLink $ binderyProperty $ " + "Obituary $ Reference $ revision $ " + "ndsCrossCertificatePair $ certificateRevocation $ " + "usedBy $ GUID $ otherGUID $ DirXML-Associations $ " + "creatorsName $ modifiersName $ unknownBaseClass $ " + "unknownAuxiliaryClass $ auditFileLink $ " + "masvProposedLabelel $ masvDefaultRange $ " + "masvAuthorizedRange $ objectVersion $ " + "auxClassCompatibility $ rbsAssignedRoles $ " + "rbsOwnedCollections $ rbsAssignedRoles2 $ " + "rbsOwnedCollections2 ) X-NDS_NONREMOVABLE '1' " + "X-NDS_ACL_TEMPLATES '16#subtree#[Creator]#[Entry Rights]' )" expect = { :name => ["Top"], :structural => ["TRUE"], :must => ["objectClass"], :x_nds_nonremovable => ["1"], :x_nds_acl_templates => ['16#subtree#[Creator]#[Entry Rights]'], } assert_schema(expect, "Top", top_schema) end def test_sup_with_oid_start_with_upper_case organizational_person_schema = "( 2.5.6.7 NAME 'organizationalPerson' SUP Person STRUCTURAL MAY " + "( facsimileTelephoneNumber $ l $ eMailAddress $ ou $ " + "physicalDeliveryOfficeName $ postalAddress $ postalCode $ " + "postOfficeBox $ st $ street $ title $ mailboxLocation $ " + "mailboxID $ uid $ mail $ employeeNumber $ destinationIndicator $ " + "internationaliSDNNumber $ preferredDeliveryMethod $ " + "registeredAddress $ teletexTerminalIdentifier $ telexNumber $ " + "x121Address $ businessCategory $ roomNumber $ x500UniqueIdentifier " + ") X-NDS_NAMING ( 'cn' 'ou' 'uid' ) X-NDS_CONTAINMENT ( " + "'Organization' 'organizationalUnit' 'domain' ) X-NDS_NAME " + "'Organizational Person' X-NDS_NOT_CONTAINER '1' " + "X-NDS_NONREMOVABLE '1' )" expect = { :name => ["organizationalPerson"], :sup => ["Person"], :structural => ["TRUE"], :x_nds_naming => ["cn", "ou", "uid"], :x_nds_containment => ["Organization", "organizationalUnit", "domain"], :x_nds_name => ["Organizational Person"], :x_nds_not_container => ["1"], :x_nds_nonremovable => ["1"], } assert_schema(expect, "organizationalPerson", organizational_person_schema) end def test_text_oid text_oid_schema = "( mysite-oid NAME 'mysite' " + "SUP groupofuniquenames STRUCTURAL " + "MUST ( mysitelang $ mysiteurl ) " + "MAY ( mysitealias $ mysitecmsurl ) " + "X-ORIGIN 'user defined' )" expect = { :name => ["mysite"], :sup => ["groupofuniquenames"], :structural => ["TRUE"], :must => %w(mysitelang mysiteurl), :may => %w(mysitealias mysitecmsurl), :x_origin => ["user defined"] } assert_schema(expect, "mysite", text_oid_schema) text_oid_attribute_schema = "( mysiteurl-oid NAME 'mysiteurl' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " + "SINGLE-VALUE X-ORIGIN 'user defined' )" expect = { :name => ["mysiteurl"], :syntax => ["1.3.6.1.4.1.1466.115.121.1.15"], :single_value => ["TRUE"], :x_origin => ["user defined"] } assert_schema(expect, "mysiteurl", text_oid_attribute_schema) end def test_name_as_key top_schema = "( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' " + "ABSTRACT MUST objectClass )" expect = { :name => ["top"], :desc => ['top of the superclass chain'], :abstract => ["TRUE"], :must => ["objectClass"] } assert_schema(expect, "2.5.6.0", top_schema) assert_schema(expect, "top", top_schema) end def test_name_as_key_for_multiple_name uid_schema = "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) " + "DESC 'RFC1274: user identifier' EQUALITY caseIgnoreMatch " + "SUBSTR caseIgnoreSubstringsMatch " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )" expect = { :name => ["uid", "userid"], :desc => ['RFC1274: user identifier'], :equality => ["caseIgnoreMatch"], :substr => ["caseIgnoreSubstringsMatch"], :syntax => ["1.3.6.1.4.1.1466.115.121.1.15{256}"], } assert_schema(expect, "0.9.2342.19200300.100.1.1", uid_schema) assert_schema(expect, "uid", uid_schema) assert_schema(expect, "userid", uid_schema) end def test_dollar dn_match_schema = "( 2.5.13.1 NAME 'distinguishedNameMatch' APPLIES " + "( creatorsName $ modifiersName $ subschemaSubentry " + "$ namingContexts $ aliasedObjectName $ " + "distinguishedName $ seeAlso $ olcDefaultSearchBase $ " + "olcRootDN $ olcSchemaDN $ olcSuffix $ olcUpdateDN $ " + "member $ owner $ roleOccupant $ manager $ " + "documentAuthor $ secretary $ associatedName $ " + "dITRedirect ) )" expect = { :name => ["distinguishedNameMatch"], :applies => %w(creatorsName modifiersName subschemaSubentry namingContexts aliasedObjectName distinguishedName seeAlso olcDefaultSearchBase olcRootDN olcSchemaDN olcSuffix olcUpdateDN member owner roleOccupant manager documentAuthor secretary associatedName dITRedirect), } assert_schema(expect, "2.5.13.1", dn_match_schema) assert_schema(expect, "distinguishedNameMatch", dn_match_schema) end def test_dc_object dc_object_schema = "( 1.3.6.1.4.1.1466.344 NAME 'dcObject' DESC " + "'RFC2247: domain component object' SUP top " + "AUXILIARY MUST dc )" expect = { :name => ["dcObject"], :desc => ['RFC2247: domain component object'], :auxiliary => ["TRUE"], :must => ["dc"], } assert_schema(expect, "1.3.6.1.4.1.1466.344", dc_object_schema) assert_schema(expect, "dcObject", dc_object_schema) end def test_organization organization_schema = "( 2.5.6.4 NAME 'organization' DESC " + "'RFC2256: an organization' SUP top STRUCTURAL " + "MUST o MAY ( userPassword $ searchGuide $ " + "seeAlso $ businessCategory $ x121Address $ " + "registeredAddress $ destinationIndicator $ " + "preferredDeliveryMethod $ telexNumber $ " + "teletexTerminalIdentifier $ telephoneNumber $ " + "internationaliSDNNumber $ " + "facsimileTelephoneNumber $ street $ " + "postOfficeBox $ postalCode $ postalAddress $ " + "physicalDeliveryOfficeName $ st $ l $ " + "description ) )" expect = { :name => ["organization"], :desc => ['RFC2256: an organization'], :sup => ["top"], :structural => ["TRUE"], :must => ["o"], :may => %w(userPassword searchGuide seeAlso businessCategory x121Address registeredAddress destinationIndicator preferredDeliveryMethod telexNumber teletexTerminalIdentifier telephoneNumber internationaliSDNNumber facsimileTelephoneNumber street postOfficeBox postalCode postalAddress physicalDeliveryOfficeName st l description), } assert_schema(expect, "2.5.6.4", organization_schema) assert_schema(expect, "organization", organization_schema) end def test_posix_account posix_account_schema = "( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC " + "'Abstraction of an account with POSIX " + "attributes' SUP top AUXILIARY MUST ( cn $ " + "uid $ uidNumber $ gidNumber $ homeDirectory " + ") MAY ( userPassword $ loginShell $ gecos $ " + "description ) )" expect = { :name => ["posixAccount"], :desc => ['Abstraction of an account with POSIX attributes'], :sup => ["top"], :auxiliary => ["TRUE"], :must => %w(cn uid uidNumber gidNumber homeDirectory), :may => %w(userPassword loginShell gecos description), } assert_schema(expect, "1.3.6.1.1.1.2.0", posix_account_schema) assert_schema(expect, "posixAccount", posix_account_schema) end def test_jpeg_photo jpeg_photo_schema = "( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' " + "DESC 'RFC2798: a JPEG image' SYNTAX " + "1.3.6.1.4.1.1466.115.121.1.28 )" expect = { :name => ["jpegPhoto"], :desc => ['RFC2798: a JPEG image'], :syntax => ["1.3.6.1.4.1.1466.115.121.1.28"], } assert_schema(expect, "0.9.2342.19200300.100.1.60", jpeg_photo_schema) assert_schema(expect, "jpegPhoto", jpeg_photo_schema) jpeg_schema = "( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " + "X-NOT-HUMAN-READABLE 'TRUE' )" expect = { :desc => ['JPEG'], :x_not_human_readable => ["TRUE"], } assert_schema(expect, "1.3.6.1.4.1.1466.115.121.1.28", jpeg_schema) schema = ActiveLdap::Schema.new({"attributeTypes" => [jpeg_photo_schema], "ldapSyntaxes" => [jpeg_schema]}) assert(schema.attribute("jpegPhoto").binary?) end private def assert_schema(expect, name, schema) sub = "objectClasses" entry = {sub => [schema]} schema = ActiveLdap::Schema.new(entry) actual = {} normalized_expect = {} expect.each do |key, value| normalized_key = key.to_s.gsub(/_/, "-") normalized_expect[normalized_key] = value actual[normalized_key] = schema[sub, name, normalized_key] end assert_equal(normalized_expect, actual) schema end def assert_make_schema_with_empty_entries(entries) schema = ActiveLdap::Schema.new(entries) assert_equal([], schema["attributeTypes", "cn", "DESC"]) assert_equal([], schema["ldapSyntaxes", "1.3.6.1.4.1.1466.115.121.1.5", "DESC"]) assert_equal([], schema["objectClasses", "posixAccount", "MUST"]) end def assert_attribute_aliases(expected, keys, schemata, ensure_parse) group = 'attributeTypes' entry = {group => schemata} schema = ActiveLdap::Schema.new(entry) schema.send(:ensure_parse, group) if ensure_parse result = keys.collect do |key| attribute = schema.attribute(key) [attribute.name, attribute.aliases] end assert_equal(expected, result) end def assert_attribute_type(expected, name, schemata) group = 'attributeTypes' entry = {group => schemata} schema = ActiveLdap::Schema.new(entry) attribute_hash = schema.attribute(name).to_hash syntax = attribute_hash[:syntax] attribute_hash[:syntax] = syntax.id if syntax assert_equal(expected, attribute_hash) end class TestAttribute < self class TestApplyEncoding < self class TestNotBinary < self def setup super uid_schema = "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) " + "DESC 'RFC1274: user identifier' EQUALITY caseIgnoreMatch " + "SUBSTR caseIgnoreSubstringsMatch " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )" entries = { "attributeTypes" => [uid_schema], } schema = ActiveLdap::Schema.new(entries) @attribute = schema.attribute("uid") end def test_do_nothing value = "" value.force_encoding("UTF-8") @attribute.apply_encoding(value) assert_equal(Encoding::UTF_8, value.encoding) end end class TestBinary < self def setup super jpeg_schema = "( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " + "X-NOT-HUMAN-READABLE 'TRUE' )" jpeg_photo_schema = "( 0.9.2342.19200300.100.1.60 NAME 'jpegPhoto' " + "DESC 'RFC2798: a JPEG image' SYNTAX " + "1.3.6.1.4.1.1466.115.121.1.28 )" entries = { "attributeTypes" => [jpeg_photo_schema], "ldapSyntaxes" => [jpeg_schema], } schema = ActiveLdap::Schema.new(entries) @attribute = schema.attribute("jpegPhoto") end def test_string value = "" value.force_encoding("UTF-8") @attribute.apply_encoding(value) assert_equal(Encoding::ASCII_8BIT, value.encoding) end def test_array values = [""] values.each do |value| value.force_encoding("UTF-8") end @attribute.apply_encoding(values) assert_equal([Encoding::ASCII_8BIT], values.collect(&:encoding)) end def test_hash values = {:binary => ""} values.each_value do |value| value.force_encoding("UTF-8") end @attribute.apply_encoding(values) assert_equal([Encoding::ASCII_8BIT], values.each_value.collect(&:encoding)) end end end end end activeldap-5.2.4/test/test_supported_control.rb0000644000004100000410000000101513464071751022023 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestSupportedControl < Test::Unit::TestCase def supported_control(controls) ActiveLdap::SupportedControl.new(controls) end class TestPagedResults < self def paged_results?(controls) supported_control(controls).paged_results? end def test_true assert_true(paged_results?(ActiveLdap::LdapControls::PAGED_RESULTS)) end def test_false assert_true(paged_results?(ActiveLdap::LdapControls::PAGED_RESULTS)) end end end activeldap-5.2.4/test/test_groupadd.rb0000644000004100000410000000231113464071751020043 0ustar www-datawww-datarequire 'al-test-utils' class TestGroupadd < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "groupadd") end priority :must priority :normal def test_exist_group make_temporary_group do |group| assert(@group_class.exists?(group.id)) assert_equal([false, "Group #{group.id} already exists.\n"], run_command(group.id)) assert(@group_class.exists?(group.id)) end end def test_add_group ensure_delete_group("test-group") do |gid| assert_groupadd_successfully(gid) end end private def assert_groupadd_successfully(name, *args, &block) _wrap_assertion do assert(!@group_class.exists?(name)) args.concat([name]) assert_equal([true, ""], run_command(*args, &block)) assert(@group_class.exists?(name)) group = @group_class.find(name) assert_equal(name, group.id) end end def assert_groupadd_failed(name, message, *args, &block) _wrap_assertion do assert(!@group_class.exists?(name)) args.concat([name]) assert_equal([false, message], run_command(*args, &block)) assert(!@group_class.exists?(name)) end end end activeldap-5.2.4/test/test_user_password.rb0000644000004100000410000001461013464071751021143 0ustar www-datawww-datarequire 'al-test-utils' class TestUserPassword < Test::Unit::TestCase priority :must priority :normal def test_valid? { "{CRYPT}.yNLaKqtwQbnY" => 'wibble', #CRYPT "{MD5}DRB9CfW75Ayt495ccenptw==" => 'letmein', #MD5 "{SMD5}8L2iXJuazftLVHrAf7ptPFQIDaw=" => 'letmein', #SMD5 as generated by slappasswd (4 bytes of salt) "{SMD5}kXibTNG+O98gaQtkugYcmSTiE+M2Z5TA" => 'letmein', #SMD5 as generated by Apache Directory Studio (8 bytes of salt) "{SMD5}4PkkYH5qI6ydk/9pwvZD3DYwYzVlMzVlLTBkZDEtNGJhMi05NjI5LWRlODgyMDhiMWZmYQ==" => 'letmein', #SMD5 generated with 36 bytes of salt "{SHA}t6h1/B6iKLkGEEG3zsS9PFKrPOM=" => 'letmein', #SHA "{SSHA}YA87hc9/L/cCGR1HValcJb7a8AYxZXY4" => 'wibble', # SSHA as generated by slappasswd (4 bytes of salt) "{SSHA}6J6Ios3l1panY9sm0+g9l3/jFz2kwOPrVA4+OA==" => 'letmein', # SSHA as generated by Apache Directory Studio (8 bytes of salt) "{SSHA}f/j1unqoJg1C1zjw8tvxSp4xpow2MGM1ZTM1ZS0wZGQxLTRiYTItOTYyOS1kZTg4MjA4YjFmZmE=" => 'letmein', #SSHA generated with 36 bytes of salt "letmein" => 'letmein', #Cleartext password }.each do |hash, plain| assert_send([ActiveLdap::UserPassword, :valid?, plain, hash]) assert_not_send([ActiveLdap::UserPassword, :valid?, "not#{plain}", hash]) end end sub_test_case("crypt") do def test_encrypt salt = ".WoUoU9f3IlUx9Hh7D/8y.xA6ziklGib" assert_equal("{CRYPT}.W57FZhV52w0s", ActiveLdap::UserPassword.crypt("password", salt)) password = "PASSWORD" hashed_password = ActiveLdap::UserPassword.crypt(password) salt = hashed_password.sub(/^\{CRYPT\}/, '') assert_equal(hashed_password, ActiveLdap::UserPassword.crypt(password, salt)) end sub_test_case("extract_salt") do sub_test_case("base format") do def test_less message = "salt size must be 2: " assert_raise(ArgumentError.new(message)) do extract_salt(:crypt, "a") end end def test_exact assert_extract_salt(:crypt, "ab", "ab") end def test_more assert_extract_salt(:crypt, "ab", "abc") end end sub_test_case("glibc2 format") do sub_test_case("ID") do def test_md5 assert_extract_salt(:crypt, "$1$abcdefgh$", "$1$abcdefgh$") end def test_blowfish assert_extract_salt(:crypt, "$2a$abcdefgh$", "$2a$abcdefgh$") end def test_sha256 assert_extract_salt(:crypt, "$5$abcdefgh$", "$5$abcdefgh$") end def test_sha512 assert_extract_salt(:crypt, "$6$abcdefgh$", "$6$abcdefgh$") end end sub_test_case("salt") do def test_not_teminated message = "salt character must be [a-zA-Z0-9./]: <$1>" assert_raise(ArgumentError.new(message)) do extract_salt(:crypt, "$1$") end end def test_empty assert_extract_salt(:crypt, "$1$$", "$1$$") end def test_lower_case assert_extract_salt(:crypt, "$1$abc$", "$1$abc$") end def test_upper_case assert_extract_salt(:crypt, "$1$ABC$", "$1$ABC$") end def test_digit assert_extract_salt(:crypt, "$1$012$", "$1$012$") end def test_dot assert_extract_salt(:crypt, "$1$...$", "$1$...$") end def test_slash assert_extract_salt(:crypt, "$1$///$", "$1$///$") end def test_mix assert_extract_salt(:crypt, "$1$aA0./$", "$1$aA0./$") end def test_max assert_extract_salt(:crypt, "$1$0123456789abcdef$", "$1$0123456789abcdef$") end def test_over message = "salt character must be [a-zA-Z0-9./]: <$1>" assert_raise(ArgumentError.new(message)) do extract_salt(:crypt, "$1$0123456789abcdefg$") end end end end end end def test_md5 assert_equal("{MD5}X03MO1qnZdYdgyfeuILPmQ==", ActiveLdap::UserPassword.md5("password")) end def test_smd5 assert_equal("{SMD5}gjz+SUSfZaux99Xsji/No200cGI=", ActiveLdap::UserPassword.smd5("password", "m4pb")) password = "PASSWORD" hashed_password = ActiveLdap::UserPassword.smd5(password) salt = decode64(hashed_password.sub(/^\{SMD5\}/, ''))[-4, 4] assert_equal(hashed_password, ActiveLdap::UserPassword.smd5(password, salt)) end def test_extract_salt_for_smd5 assert_extract_salt(:smd5, 'this', encode64("1234567890123456this")) assert_extract_salt(:smd5, 'this is the salt', encode64("1234567890123456this is the salt")) assert_extract_salt(:smd5, nil, encode64("123456789")) assert_extract_salt(:smd5, nil, encode64("123456789012345")) assert_extract_salt(:smd5, nil, encode64("1234567890123456")) end def test_sha assert_equal("{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=", ActiveLdap::UserPassword.sha("password")) end def test_ssha assert_equal("{SSHA}ipnlCLA1HaK3mm3hyneJIp+Px2h1RGk3", ActiveLdap::UserPassword.ssha("password", "uDi7")) password = "PASSWORD" hashed_password = ActiveLdap::UserPassword.ssha(password) salt = decode64(hashed_password.sub(/^\{SSHA\}/, ''))[-4, 4] assert_equal(hashed_password, ActiveLdap::UserPassword.ssha(password, salt)) end def test_extract_salt_for_ssha assert_extract_salt(:ssha, 'this', encode64("12345678901234567890this")) assert_extract_salt(:ssha, 'this is the salt', encode64("12345678901234567890this is the salt")) assert_extract_salt(:ssha, nil, encode64("12345678901234")) assert_extract_salt(:ssha, nil, encode64("1234567890123456789")) assert_extract_salt(:ssha, nil, encode64("12345678901234567890")) end private def extract_salt(type, hashed_password) ActiveLdap::UserPassword.send("extract_salt_for_#{type}", hashed_password) end def assert_extract_salt(type, expected, hashed_password) assert_equal(expected, extract_salt(type, hashed_password)) end def encode64(string) [string].pack('m').chomp end def decode64(string) string.unpack('m')[0] end end activeldap-5.2.4/test/command.rb0000644000004100000410000000505213464071751016622 0ustar www-datawww-datarequire "thread" require "socket" require "shellwords" module Command class Error < StandardError attr_reader :command, :result def initialize(command, result) @command = command @result = result super("#{command}: #{result}") end end module_function def detach_io require 'fcntl' [TCPSocket, ::File].each do |c| ObjectSpace.each_object(c) do |io| begin unless io.closed? io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) end rescue SystemCallError, IOError end end end end def run(cmd, *args, &block) raise ArgumentError, "command isn't specified" if cmd.nil? if args.any? {|x| x.nil?} raise ArgumentError, "args has nil: #{args.inspect}" end args = args.collect {|arg| arg.to_s} return java_run(cmd, *args, &block) if Object.respond_to?(:java) in_r, in_w = IO.pipe out_r, out_w = IO.pipe verbose = $VERBOSE # ruby(>=1.8)'s fork terminates other threads with warning messages $VERBOSE = nil pid = fork do $VERBOSE = verbose detach_io STDIN.reopen(in_r) in_r.close STDOUT.reopen(out_w) STDERR.reopen(out_w) out_w.close exec(cmd, *args) exit!(-1) end $VERBOSE = verbose yield(out_r, in_w) if block_given? in_r.close unless in_r.closed? out_w.close unless out_w.closed? pid, status = Process.waitpid2(pid) [status.exited? && status.exitstatus.zero?, out_r.read] end def java_run(cmd, *args, &block) runtime = java.lang.Runtime.get_runtime process = runtime.exec([cmd, *args].to_java(:string)) input = JavaReaderWrapper.new(process.get_input_stream) output = JavaWriterWrapper.new(process.get_output_stream) error = JavaReaderWrapper.new(process.get_error_stream) yield(input, output) if block_given? output.close success = process.wait_for.zero? [success, input.read + error.read] end class JavaReaderWrapper def initialize(input) @input = input end def read result = "" while (c = @input.read) != -1 result << c.chr end result end end class JavaWriterWrapper def initialize(output) output = java.io.OutputStreamWriter.new(output) @output = java.io.BufferedWriter.new(output) end def puts(*messages) messages.each do |message| message += "\n" if /\n/ !~ message @output.write(message) end end def flush @output.flush end def close @output.close end end end activeldap-5.2.4/test/test_usermod.rb0000644000004100000410000000316013464071751017717 0ustar www-datawww-datarequire 'al-test-utils' class TestUsermod < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "usermod") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_user ensure_delete_user("test-user") do |uid,| assert(!@user_class.exists?(uid)) assert_equal([false, "User #{uid} doesn't exist.\n"], run_command(uid, "New CN", 11111)) assert(!@user_class.exists?(uid)) end end def test_modify_user make_temporary_user do |user, password| assert_usermod_successfully(user.uid, "New #{user.cn}", user.uid_number.to_i + 100) end end private def assert_usermod_successfully(name, cn, uid, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([true, ""], run_command(*args, &block)) assert(@user_class.exists?(name)) user = @user_class.find(name) assert_equal(name, user.uid) assert_equal(cn, user.cn) assert_equal(uid.to_i, user.uid_number) assert_equal(uid.to_i, user.gid_number) assert_equal(uid.to_s, user.uid_number_before_type_cast) assert_equal(uid.to_s, user.gid_number_before_type_cast) end end def assert_usermod_failed(name, cn, uid, message, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([false, message], run_command(*args, &block)) assert(@user_class.exists?(name)) end end end activeldap-5.2.4/test/test_find.rb0000644000004100000410000001531113464071751017162 0ustar www-datawww-datarequire 'al-test-utils' class TestFind < Test::Unit::TestCase include AlTestUtils priority :must def test_find_with_dn make_temporary_user do |user,| assert_equal(user.dn, @user_class.find(user.dn).dn) assert_equal(user.dn, @user_class.find(ActiveLdap::DN.parse(user.dn)).dn) end end priority :normal def test_find_with_special_value_prefix # \2C == ',' make_ou("a\\2Cb,ou=Users") make_temporary_user(:uid => "user1,ou=a\\2Cb") do |user1,| assert_equal([], @user_class.find(:all, :prefix => "ou=a,b").collect(&:dn)) params = {:prefix => "ou=a\\2Cb"} assert_equal([user1.dn], @user_class.find(:all, params).collect(&:dn)) params = {:prefix => [["ou", "a,b"]]} assert_equal([user1.dn], @user_class.find(:all, params).collect(&:dn)) end end def test_find_with_special_value_base # \5C == '\' make_ou("a\\5Cb,ou=Users") make_temporary_user(:uid => "user1,ou=a\\5Cb") do |user1,| base = @user_class.base params = {:base => "ou=a\\b,#{base}"} assert_equal([], @user_class.find(:all, params).collect(&:dn)) params = {:base => "ou=a\\5Cb,#{base}"} assert_equal([user1.dn], @user_class.find(:all, params).collect(&:dn)) base_rdns = ActiveLdap::DN.parse(base).rdns params = {:base => [["ou", "a\\b"]] + base_rdns} assert_equal([user1.dn], @user_class.find(:all, params).collect(&:dn)) end end def test_find_with_sort_by_in_ldap_mapping @user_class.ldap_mapping(:dn_attribute => @user_class.dn_attribute, :prefix => @user_class.prefix, :scope => @user_class.scope, :classes => @user_class_classes, :sort_by => "uid", :order => "desc") make_temporary_user(:uid => "user1") do |user1,| make_temporary_user(:uid => "user2") do |user2,| make_temporary_user(:uid => "user3") do |user3,| users = @user_class.find(:all) assert_equal(["user3", "user2", "user1"], users.collect {|u| u.uid}) users = @user_class.find(:all, :order => "asc") assert_equal(["user1", "user2", "user3"], users.collect {|u| u.uid}) end end end end def test_find_operational_attributes make_temporary_user do |user, password| found_user = @user_class.find(user.uid, :include_operational_attributes => true) assert_equal(Time.now.utc.iso8601, found_user.modify_timestamp.utc.iso8601) end end def test_find_with_attributes_without_object_class make_temporary_user do |user, password| found_user = @user_class.find(user.uid, :attributes => ["uidNumber"]) assert_equal(user.uid_number, found_user.uid_number) assert_equal(user.classes, found_user.classes) assert_nil(found_user.gid_number) end end def test_find_with_integer_value make_temporary_user do |user, password| found_user = @user_class.find(:attribute => "gidNumber", :value => user.gid_number) assert_equal(user.dn, found_user.dn) end end def test_find_with_limit make_temporary_user(:uid => "user1") do |user1,| make_temporary_user(:uid => "user2") do |user2,| make_temporary_user(:uid => "user3") do |user3,| users = @user_class.find(:all) assert_equal(["user1", "user2", "user3"].sort, users.collect {|u| u.uid}.sort) users = @user_class.find(:all, :limit => 2) assert_operator([["user1", "user2"].sort, ["user2", "user3"].sort, ["user3", "user1"].sort], :include?, users.collect {|u| u.uid}.sort) users = @user_class.find(:all, :limit => 1) assert_operator([["user1"], ["user2"], ["user3"]], :include?, users.collect {|u| u.uid}) end end end end def test_find_all_with_dn_attribute_value make_temporary_user(:uid => "user1") do |user1,| make_temporary_user(:uid => "user2") do |user2,| assert_equal(["user1"], @user_class.find(:all, "*1").collect {|u| u.uid}) end end end def test_find_with_sort make_temporary_user(:uid => "user1") do |user1,| make_temporary_user(:uid => "user2") do |user2,| users = @user_class.find(:all, :sort_by => "uid", :order => 'asc') assert_equal(["user1", "user2"], users.collect {|u| u.uid}) users = @user_class.find(:all, :sort_by => "uid", :order => 'desc') assert_equal(["user2", "user1"], users.collect {|u| u.uid}) users = @user_class.find(:all, :order => 'asc') assert_equal(["user1", "user2"], users.collect {|u| u.uid}) users = @user_class.find(:all, :order => 'desc') assert_equal(["user2", "user1"], users.collect {|u| u.uid}) users = @user_class.find(:all, :order => 'asc', :limit => 1) assert_equal(["user1"], users.collect {|u| u.uid}) users = @user_class.find(:all, :order => 'desc', :limit => 1) assert_equal(["user2"], users.collect {|u| u.uid}) end end end def test_split_search_value assert_split_search_value([nil, "test-user", nil], "test-user") assert_split_search_value([nil, "test-user", "ou=Sub"], "test-user,ou=Sub") assert_split_search_value(["uid", "test-user", "ou=Sub"], "uid=test-user,ou=Sub") assert_split_search_value(["uid", "test-user", nil], "uid=test-user") end def test_find make_temporary_user do |user, password| assert_equal(user.uid, @user_class.find(:first).uid) assert_equal(user.uid, @user_class.find(user.uid).uid) options = {:attribute => "cn", :value => user.cn} assert_equal(user.uid, @user_class.find(:first, options).uid) assert_equal(user.uid, @user_class.find(options).uid) assert_equal(user.to_ldif, @user_class.find(:first).to_ldif) assert_equal([user.uid], @user_class.find(:all).collect {|u| u.uid}) make_temporary_user do |user2, password2| assert_equal(user2.uid, @user_class.find(user2.uid).uid) assert_equal([user2.uid], @user_class.find(user2.uid(true)).collect {|u| u.uid}) assert_equal(user2.to_ldif, @user_class.find(user2.uid).to_ldif) assert_equal([user.uid, user2.uid].sort, @user_class.find(:all).collect {|u| u.uid}.sort) end end end private def assert_split_search_value(expected, value) assert_equal(expected, ActiveLdap::Base.send(:split_search_value, value)) end end activeldap-5.2.4/test/test_usermod-lang-add.rb0000644000004100000410000000336513464071751021373 0ustar www-datawww-datarequire 'al-test-utils' class TestUsermodLangAdd < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "usermod-lang-add") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_user ensure_delete_user("test-user") do |uid,| assert(!@user_class.exists?(uid)) assert_equal([false, "User #{uid} doesn't exist.\n"], run_command(uid, "New CN", 11111)) assert(!@user_class.exists?(uid)) end end def test_modify_user make_temporary_user do |user, password| assert_usermod_lang_add_successfully(user.uid, "New #{user.cn}", user.uid_number.to_i + 100) end end private def assert_usermod_lang_add_successfully(name, cn, uid, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([true, ""], run_command(*args, &block)) assert(@user_class.exists?(name)) user = @user_class.find(name) assert_equal(name, user.uid) assert_equal([cn, {'lang-en-us' => cn}].sort_by(&:inspect), user.cn.sort_by(&:inspect)) assert_equal(uid.to_i, user.uid_number) assert_equal(uid.to_i, user.gid_number) assert_equal(uid.to_s, user.uid_number_before_type_cast) assert_equal(uid.to_s, user.gid_number_before_type_cast) end end def assert_usermod_lang_add_failed(name, cn, uid, message, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([false, message], run_command(*args, &block)) assert(@user_class.exists?(name)) end end end activeldap-5.2.4/test/test_connection_per_class.rb0000644000004100000410000001055613464071751022442 0ustar www-datawww-datarequire 'al-test-utils' class TestConnectionPerClass < Test::Unit::TestCase include AlTestUtils priority :must def test_multi_setup_connections_with_association make_ou("Sub,ou=Users") make_ou("Sub2,ou=Users") sub_user_class = Class.new(@user_class) sub_user_class.prefix = "ou=Sub" sub2_user_class = Class.new(@user_class) sub2_user_class.prefix = "ou=Sub2" sub_user_class.has_many(:related_entries, :wrap => "seeAlso") sub_user_class.set_associated_class(:related_entries, sub2_user_class) make_temporary_user(:uid => "uid=user1,ou=Sub") do |user,| make_temporary_user(:uid => "uid=user2,ou=Sub2") do |user2,| sub_user = sub_user_class.find(user.uid) sub2_user = sub2_user_class.find(user2.uid) sub_user.see_also = sub2_user.dn assert(sub_user.save) sub_user = sub_user_class.find(user.uid) assert_equal(["ou=Sub2"], sub_user.related_entries.collect {|e| e.class.prefix}) end end end priority :normal def test_multi_setup_connections make_ou("Sub") make_ou("Sub2") sub_class = ou_class("ou=Sub") sub2_class = ou_class("ou=Sub2") configuration = current_configuration.symbolize_keys configuration[:scope] = :base current_base = configuration[:base] sub_configuration = configuration.dup sub_base = "ou=Sub,#{current_base}" sub_configuration[:base] = sub_base sub2_configuration = configuration.dup sub2_base = "ou=Sub2,#{current_base}" sub2_configuration[:base] = sub2_base sub_class.setup_connection(sub_configuration) sub_class.prefix = nil sub2_class.setup_connection(sub2_configuration) sub2_class.prefix = nil assert_equal([sub_base], sub_class.find(:all).collect(&:dn)) assert_equal([sub2_base], sub2_class.find(:all).collect(&:dn)) assert_equal([sub_base], sub_class.find(:all).collect(&:dn)) assert_equal([sub2_base], sub2_class.find(:all).collect(&:dn)) end def test_multi_same_setup_connections make_ou("Sub") sub_class1 = ou_class("ou=Sub") sub_class2 = ou_class("ou=Sub") configuration = current_configuration.symbolize_keys configuration[:scope] = :base current_base = configuration[:base] sub_configuration = configuration.dup sub_base = "ou=Sub,#{current_base}" sub_configuration[:base] = sub_base sub_class1.setup_connection(sub_configuration) sub_class2.setup_connection(sub_configuration) sub_configuration1 = sub_class1.configuration sub_configuration2 = sub_class2.configuration assert_not_nil(sub_configuration1) assert_not_nil(sub_configuration2) sub_class1.setup_connection(sub_configuration.dup) sub_class1.prefix = nil assert_equal([ sub_configuration1, sub_configuration2, ], [ sub_class1.configuration, sub_class2.configuration, ]) end def test_bind non_anon_class = ou_class("ou=NonAnonymous") anon_class = ou_class("ou=Anonymous") assert(non_anon_class.connection.bound?) assert(anon_class.connection.bound?) anon_class.connection.unbind assert(!non_anon_class.connection.bound?) assert(!anon_class.connection.bound?) anon_class.connection.rebind assert(non_anon_class.connection.bound?) assert(anon_class.connection.bound?) assert_raises(ActiveLdap::AuthenticationError) do connect(non_anon_class, :bind_dn => nil, :allow_anonymous => false, :retry_limit => 0) end assert(!non_anon_class.connection.bound?) assert(anon_class.connection.bound?) anon_class.connection.unbind assert(!non_anon_class.connection.bound?) assert(!anon_class.connection.bound?) anon_class.connection.rebind assert(!non_anon_class.connection.bound?) assert(anon_class.connection.bound?) anon_class.connection.unbind assert(!non_anon_class.connection.bound?) assert(!anon_class.connection.bound?) assert_nothing_raised do connect(anon_class, :bind_dn => nil, :allow_anonymous => true) end assert(!non_anon_class.connection.bound?) assert(anon_class.connection.bound?) end private def connect(klass, config) klass.setup_connection({:adapter => adapter}.merge(config)) klass.connection.connect end end activeldap-5.2.4/test/test_ldif.rb0000644000004100000410000014634213464071751017171 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestLDIF < Test::Unit::TestCase include ActiveLdap::GetTextSupport include AlTestUtils::Config include AlTestUtils::ExampleFile priority :must def test_integer_attribute_value_to_s dn = ActiveLdap::DN.parse("uid=user,ou=People,dc=example,dc=com") record = ActiveLdap::Ldif::Record.new(dn, {"uidNumber" => [100]}) assert_equal(<<-EOL, record.to_s) dn: uid=user,ou=People,dc=example,dc=com uidNumber: 100 EOL end priority :normal def test_accept_empty_lines_after_content ldif_source = <<-EOL version: 1 dn: dc=devel,dc=example,dc=com dc: devel objectClass: top objectClass: dcObject objectClass: organization o: devel EOL expected_ldif_to_s = <<-EOL version: 1 dn: dc=devel,dc=example,dc=com dc: devel o: devel objectClass: dcObject objectClass: organization objectClass: top EOL assert_ldif_to_s(expected_ldif_to_s, ldif_source) assert_ldif_to_s(expected_ldif_to_s, ldif_source + "\n") assert_ldif_to_s(expected_ldif_to_s, ldif_source + "\n\n") assert_ldif_to_s(expected_ldif_to_s, ldif_source + ("\n" * 10)) end def test_accept_comments_after_content ldif_source = <<-EOL version: 1 dn: dc=devel,dc=example,dc=com dc: devel objectClass: top objectClass: dcObject objectClass: organization o: devel # search result # numResponse: 1 # numEntries: 1 EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: dc=devel,dc=example,dc=com dc: devel o: devel objectClass: dcObject objectClass: organization objectClass: top EOL end def test_comments_and_empty_lines_before_content ldif_source = <<-EOL version: 1 # # LDAPv3 # base with scope subtree # filter: (objectclass=*) # requesting: ALL # # devel.example.com dn: dc=devel,dc=example,dc=com dc: devel objectClass: top objectClass: dcObject objectClass: organization o: devel EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: dc=devel,dc=example,dc=com dc: devel o: devel objectClass: dcObject objectClass: organization objectClass: top EOL end def test_unknown_change_type ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: XXX EOL ldif_source_with_error_mark = <<-EOL changetype: |@|XXX EOL assert_invalid_ldif(["unknown change type: %s", "XXX"], ldif_source, 3, 13, ldif_source_with_error_mark) end def test_unknown_modify_type ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: modify XXX: postaladdress - EOL ldif_source_with_error_mark = <<-EOL |@|XXX: postaladdress EOL assert_invalid_ldif(["unknown modify type: %s", "XXX"], ldif_source, 4, 1, ldif_source_with_error_mark) end def test_modify_spec_block_separator_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: modify add: postaladdress EOL ldif_source_with_error_mark = <<-EOL.chomp add: postaladdress |@| EOL assert_invalid_ldif("'-' is missing", ldif_source, 5, 1, ldif_source_with_error_mark) end def test_modify_spec_first_line_separator_is_missing ldif_source = <<-EOL.chomp version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: modify add: postaladdress EOL ldif_source_with_error_mark = <<-EOL.chomp add: postaladdress|@| EOL assert_invalid_ldif("separator is missing", ldif_source, 4, 19, ldif_source_with_error_mark) end def test_modify_target_attribute_name_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: modify add: - EOL ldif_source_with_error_mark = <<-EOL add:|@| EOL assert_invalid_ldif("attribute type is missing", ldif_source, 4, 5, ldif_source_with_error_mark) end def test_newsuperior_separator_is_missing ldif_source = <<-EOL.chomp version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen deleteoldrdn: 1 newsuperior: ou=Accounting, dc=airius, dc=com EOL ldif_source_with_error_mark = <<-EOL.chomp newsuperior: ou=Accounting, dc=airius, dc=com|@| EOL assert_invalid_ldif("separator is missing", ldif_source, 6, 46, ldif_source_with_error_mark) end def test_newsuperior_value_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen deleteoldrdn: 1 newsuperior: EOL ldif_source_with_error_mark = <<-EOL newsuperior:|@| EOL assert_invalid_ldif("new superior value is missing", ldif_source, 6, 13, ldif_source_with_error_mark) end def test_deleteoldrdn_separator_is_missing ldif_source = <<-EOL.chomp version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen deleteoldrdn: 1 EOL ldif_source_with_error_mark = <<-EOL.chomp deleteoldrdn: 1|@| EOL assert_invalid_ldif("separator is missing", ldif_source, 5, 16, ldif_source_with_error_mark) end def test_invalid_deleteoldrdn_value ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen deleteoldrdn: x EOL ldif_source_with_error_mark = <<-EOL deleteoldrdn: |@|x EOL assert_invalid_ldif("delete old RDN value is missing", ldif_source, 5, 15, ldif_source_with_error_mark) end def test_deleteoldrdn_value_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen deleteoldrdn: EOL ldif_source_with_error_mark = <<-EOL deleteoldrdn:|@| EOL assert_invalid_ldif("delete old RDN value is missing", ldif_source, 5, 14, ldif_source_with_error_mark) end def test_deleteoldrdn_mark_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen EOL ldif_source_with_error_mark = <<-EOL.chomp newrdn: cn=Paula Jensen |@| EOL assert_invalid_ldif("'deleteoldrdn:' is missing", ldif_source, 5, 1, ldif_source_with_error_mark) end def test_newrdn_separator_is_missing ldif_source = <<-EOL.chomp version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen EOL ldif_source_with_error_mark = <<-EOL.chomp newrdn: cn=Paula Jensen|@| EOL assert_invalid_ldif("separator is missing", ldif_source, 4, 24, ldif_source_with_error_mark) end def test_newrdn_value_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: EOL ldif_source_with_error_mark = <<-EOL newrdn:|@| EOL assert_invalid_ldif("new RDN value is missing", ldif_source, 4, 8, ldif_source_with_error_mark) end def test_newrdn_mark_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: moddn EOL ldif_source_with_error_mark = <<-EOL.chomp changetype: moddn |@| EOL assert_invalid_ldif("'newrdn:' is missing", ldif_source, 4, 1, ldif_source_with_error_mark) end def test_add_change_type_without_attribute ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: add EOL ldif_source_with_error_mark = <<-EOL.chomp changetype: add |@| EOL assert_invalid_ldif("attribute spec is missing", ldif_source, 4, 1, ldif_source_with_error_mark) end def test_change_type_with_an_extra_space ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: delete EOL ldif_source_with_error_mark = <<-EOL changetype: delete|@| EOL assert_invalid_ldif("separator is missing", ldif_source, 3, 19, ldif_source_with_error_mark) end def test_change_type_separator_is_missing ldif_source = <<-EOL.chomp version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: delete EOL ldif_source_with_error_mark = <<-EOL.chomp changetype: delete|@| EOL assert_invalid_ldif("separator is missing", ldif_source, 3, 19, ldif_source_with_error_mark) end def test_change_type_value_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: EOL ldif_source_with_error_mark = <<-EOL changetype:|@| EOL assert_invalid_ldif("change type value is missing", ldif_source, 3, 12, ldif_source_with_error_mark) end def test_control_separator_is_missing ldif_source = <<-EOL.chomp version: 1 dn: ou=Product Development, dc=airius, dc=com control: 1.2.840.113556.1.4.805 true EOL ldif_source_with_error_mark = <<-EOL.chomp control: 1.2.840.113556.1.4.805 true|@| EOL assert_invalid_ldif("separator is missing", ldif_source, 3, 37, ldif_source_with_error_mark) end def test_criticality_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com control: 1.2.840.113556.1.4.805 EOL ldif_source_with_error_mark = <<-EOL control: 1.2.840.113556.1.4.805 |@| EOL assert_invalid_ldif("criticality is missing", ldif_source, 3, 33, ldif_source_with_error_mark) end def test_control_type_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com control: EOL ldif_source_with_error_mark = <<-EOL control:|@| EOL assert_invalid_ldif("control type is missing", ldif_source, 3, 9, ldif_source_with_error_mark) end def test_change_type_is_missing ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com control: 1.2.840.113556.1.4.805 true EOL ldif_source_with_error_mark = <<-EOL.chomp control: 1.2.840.113556.1.4.805 true |@| EOL assert_invalid_ldif("change type is missing", ldif_source, 4, 1, ldif_source_with_error_mark) end def test_invalid_dn ldif_source = <<-EOL version: 1 dn: ou=o=Airius EOL ldif_source_with_error_mark = <<-EOL dn: ou=o=Airius|@| EOL assert_invalid_ldif(["DN is invalid: %s: %s", "ou=o=Airius", "attribute type is missing"], ldif_source, 2, 16, ldif_source_with_error_mark) end def test_invalid_dn_value ldif_source = <<-EOL version: 1 # dn:: ou=,o=Airius dn: ou=営業部,o=Airius EOL ldif_source_with_error_mark = <<-EOL dn: ou=|@|営業部,o=Airius EOL assert_invalid_ldif(["DN has an invalid character: %s", "営"], ldif_source, 3, 8, ldif_source_with_error_mark) end def test_multi_records_without_separator ldif_source = <<-EOL version: 1 dn: ou=Product Development, dc=airius, dc=com changetype: delete dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com seealso: description:: EOL ldif_source_with_error_mark = <<-EOL |@|dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com EOL assert_invalid_ldif("separator is missing", ldif_source, 4, 1, ldif_source_with_error_mark) end def test_to_s_with_blank_value ldif_source = <<-EOL version: 1 dn: ou=Product Development,dc=airius,dc=com seealso: description:: EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: ou=Product Development,dc=airius,dc=com description: seealso: EOL end def test_to_s_with_last_space ldif_source = <<-EOL version: 1 # 'ou=Product Development,dc=airius,dc=com ' dn:: b3U9UHJvZHVjdCBEZXZlbG9wbWVudCwgZGM9YWlyaXVzLCBkYz1jb20g # 'ou=Product Development,dc=airius,dc=com ' description:: b3U9UHJvZHVjdCBEZXZlbG9wbWVudCwgZGM9YWlyaXVzLCBkYz1jb20g EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: ou=Product Development,dc=airius,dc="com " description:: b3U9UHJvZHVjdCBEZXZlbG9wbWVudCwgZGM9YWlyaXVzLCBkYz1jb20g EOL end def test_change_record_with_control ldif_source = <<-EOL version: 1 # Delete an entry. The operation will attach the LDAPv3 # Tree Delete Control defined in [9]. The criticality # field is "true" and the controlValue field is # absent, as required by [9]. dn: ou=Product Development, dc=airius, dc=com control: 1.2.840.113556.1.4.805 true changetype: delete EOL change_attributes = { "dn" => "ou=Product Development,dc=airius,dc=com", } ldif = assert_ldif(1, [change_attributes], ldif_source) record = ldif.records[0] assert_equal("delete", record.change_type) assert_true(record.delete?) assert_equal([{ :type => "1.2.840.113556.1.4.805", :criticality => true, :value => nil }], record.controls.collect {|control| control.to_hash}) control = record.controls[0] assert_equal("1.2.840.113556.1.4.805", control.type) assert_true(control.criticality?) assert_nil(control.value) end def test_change_record_with_control_to_s ldif_source = <<-EOL version: 1 # Delete an entry. The operation will attach the LDAPv3 # Tree Delete Control defined in [9]. The criticality # field is "true" and the controlValue field is # absent, as required by [9]. dn: ou=Product Development, dc=airius, dc=com control: 1.2.840.113556.1.4.805 true changetype: delete EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: ou=Product Development,dc=airius,dc=com control: 1.2.840.113556.1.4.805 true changetype: delete EOL end def test_multi_change_type_records ldif_source = <<-EOL version: 1 # Add a new entry dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com changetype: add objectclass: top objectclass: person objectclass: organizationalPerson cn: Fiona Jensen sn: Jensen uid: fiona telephonenumber: +1 408 555 1212 # Delete an existing entry dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com changetype: delete # Modify an entry's relative distinguished name dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com changetype: modrdn newrdn: cn=Paula Jensen deleteoldrdn: 1 # Rename an entry and move all of its children to a new location in # the directory tree (only implemented by LDAPv3 servers). dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com changetype: modrdn newrdn: ou=Product Development Accountants deleteoldrdn: 0 newsuperior: ou=Accounting, dc=airius, dc=com # Modify an entry: add an additional value to the postaladdress # attribute, completely delete the description attribute, replace # the telephonenumber attribute with two values, and delete a specific # value from the facsimiletelephonenumber attribute dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com changetype: modify add: postaladdress postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086 - delete: description - replace: telephonenumber telephonenumber: +1 408 555 1234 telephonenumber: +1 408 555 5678 - delete: facsimiletelephonenumber facsimiletelephonenumber: +1 408 555 9876 - # Modify an entry: replace the postaladdress attribute with an empty # set of values (which will cause the attribute to be removed), and # delete the entire description attribute. Note that the first will # always succeed, while the second will only succeed if at least # one value for the description attribute is present. dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com changetype: modify replace: postaladdress - delete: description - EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Fiona Jensen,ou=Marketing,dc=airius,dc=com changetype: add cn: Fiona Jensen objectclass: organizationalPerson objectclass: person objectclass: top sn: Jensen telephonenumber: +1 408 555 1212 uid: fiona dn: cn=Robert Jensen,ou=Marketing,dc=airius,dc=com changetype: delete dn: cn=Paul Jensen,ou=Product Development,dc=airius,dc=com changetype: modrdn newrdn: cn=Paula Jensen deleteoldrdn: 1 dn: ou=PD Accountants,ou=Product Development,dc=airius,dc=com changetype: modrdn newrdn: ou=Product Development Accountants deleteoldrdn: 0 newsuperior: ou=Accounting,dc=airius,dc=com dn: cn=Paula Jensen,ou=Product Development,dc=airius,dc=com changetype: modify add: postaladdress postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086 - delete: description - replace: telephonenumber telephonenumber: +1 408 555 1234 telephonenumber: +1 408 555 5678 - delete: facsimiletelephonenumber facsimiletelephonenumber: +1 408 555 9876 - dn: cn=Ingrid Jensen,ou=Product Support,dc=airius,dc=com changetype: modify replace: postaladdress - delete: description - EOL change_attributes_add = { "dn" => "cn=Fiona Jensen,ou=Marketing,dc=airius,dc=com", "objectclass" => ["top", "person", "organizationalPerson"], "cn" => ["Fiona Jensen"], "sn" => ["Jensen"], "uid" => ["fiona"], "telephonenumber" => ["+1 408 555 1212"], } change_attributes_delete = { "dn" => "cn=Robert Jensen,ou=Marketing,dc=airius,dc=com", } change_attributes_modrdn = { "dn" => "cn=Paul Jensen,ou=Product Development,dc=airius,dc=com", } change_attributes_modrdn_with_new_superior = { "dn" => "ou=PD Accountants,ou=Product Development,dc=airius,dc=com", } change_attributes_modify = { "dn" => "cn=Paula Jensen,ou=Product Development,dc=airius,dc=com", } change_attributes_modify_with_empty_replace = { "dn" => "cn=Ingrid Jensen,ou=Product Support,dc=airius,dc=com", } ldif = assert_ldif(1, [change_attributes_add, change_attributes_delete, change_attributes_modrdn, change_attributes_modrdn_with_new_superior, change_attributes_modify, change_attributes_modify_with_empty_replace], ldif_source) record = ldif.records[0] assert_equal("add", record.change_type) assert_true(record.add?) record = ldif.records[1] assert_equal("delete", record.change_type) assert_true(record.delete?) record = ldif.records[2] assert_equal("modrdn", record.change_type) assert_true(record.modify_rdn?) assert_equal("cn=Paula Jensen", record.new_rdn) assert_true(record.delete_old_rdn?) assert_nil(record.new_superior) record = ldif.records[3] assert_equal("modrdn", record.change_type) assert_true(record.modify_rdn?) assert_equal("ou=Product Development Accountants", record.new_rdn) assert_false(record.delete_old_rdn?) assert_equal("ou=Accounting,dc=airius,dc=com", record.new_superior) record = ldif.records[4] assert_equal("modify", record.change_type) assert_true(record.modify?) operations = [ ["add", "postaladdress", {"postaladdress" => ["123 Anystreet $ Sunnyvale, CA $ 94086"]}], ["delete", "description", {}], ["replace", "telephonenumber", {"telephonenumber" => [ "+1 408 555 1234", "+1 408 555 5678", ]}], ["delete", "facsimiletelephonenumber", {"facsimiletelephonenumber" => ["+1 408 555 9876"]}], ] i = -1 actual = record.operations.collect do |operation| i += 1 type = operations[i][0] [operation.send("#{type}?"), [operation.type, operation.attribute, operation.attributes]] end assert_equal(operations.collect {|operation| [true, operation]}, actual) record = ldif.records[5] assert_equal("modify", record.change_type) assert_true(record.modify?) operations = [ ["replace", "postaladdress", {}], ["delete", "description", {}], ] i = -1 actual = record.operations.collect do |operation| i += 1 type = operations[i][0] [operation.send("#{type}?"), [operation.type, operation.attribute, operation.attributes]] end assert_equal(operations.collect {|operation| [true, operation]}, actual) end def test_modify_record ldif_source = <<-EOL version: 1 # Modify an entry: add an additional value to the postaladdress # attribute, completely delete the description attribute, replace # the telephonenumber attribute with two values, and delete a specific # value from the facsimiletelephonenumber attribute dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com changetype: modify add: postaladdress postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086 - delete: description - replace: telephonenumber telephonenumber: +1 408 555 1234 telephonenumber: +1 408 555 5678 - delete: facsimiletelephonenumber facsimiletelephonenumber: +1 408 555 9876 - EOL change_attributes = { "dn" => "cn=Paula Jensen,ou=Product Development,dc=airius,dc=com", } ldif = assert_ldif(1, [change_attributes], ldif_source) record = ldif.records[0] assert_equal("modify", record.change_type) assert_true(record.modify?) operations = [ ["add", "postaladdress", {"postaladdress" => ["123 Anystreet $ Sunnyvale, CA $ 94086"]}], ["delete", "description", {}], ["replace", "telephonenumber", {"telephonenumber" => [ "+1 408 555 1234", "+1 408 555 5678", ]}], ["delete", "facsimiletelephonenumber", {"facsimiletelephonenumber" => ["+1 408 555 9876"]}], ] i = -1 actual = record.operations.collect do |operation| i += 1 type = operations[i][0] [operation.send("#{type}?"), [operation.type, operation.attribute, operation.attributes]] end assert_equal(operations.collect {|operation| [true, operation]}, actual) end def test_modify_record_to_s ldif_source = <<-EOL version: 1 # Modify an entry: add an additional value to the postaladdress # attribute, completely delete the description attribute, replace # the telephonenumber attribute with two values, and delete a specific # value from the facsimiletelephonenumber attribute dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com changetype: modify add: postaladdress postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086 - delete: description - replace: telephonenumber telephonenumber: +1 408 555 1234 telephonenumber: +1 408 555 5678 - delete: facsimiletelephonenumber facsimiletelephonenumber: +1 408 555 9876 - EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Paula Jensen,ou=Product Development,dc=airius,dc=com changetype: modify add: postaladdress postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086 - delete: description - replace: telephonenumber telephonenumber: +1 408 555 1234 telephonenumber: +1 408 555 5678 - delete: facsimiletelephonenumber facsimiletelephonenumber: +1 408 555 9876 - EOL end def test_modrdn_record_with_newsuperior ldif_source = <<-EOL version: 1 # Rename an entry and move all of its children to a new location in # the directory tree (only implemented by LDAPv3 servers). dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com changetype: modrdn newrdn: ou=Product Development Accountants deleteoldrdn: 0 newsuperior: ou=Accounting, dc=airius, dc=com EOL change_attributes = { "dn" => "ou=PD Accountants,ou=Product Development,dc=airius,dc=com", } ldif = assert_ldif(1, [change_attributes], ldif_source) record = ldif.records[0] assert_equal("modrdn", record.change_type) assert_true(record.modify_rdn?) assert_equal("ou=Product Development Accountants", record.new_rdn) assert_false(record.delete_old_rdn?) assert_equal("ou=Accounting,dc=airius,dc=com", record.new_superior) end def test_modrdn_record_with_newsuperior_to_s ldif_source = <<-EOL version: 1 # Rename an entry and move all of its children to a new location in # the directory tree (only implemented by LDAPv3 servers). dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com changetype: modrdn newrdn: ou=Product Development Accountants deleteoldrdn: 0 newsuperior: ou=Accounting, dc=airius, dc=com EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: ou=PD Accountants,ou=Product Development,dc=airius,dc=com changetype: modrdn newrdn: ou=Product Development Accountants deleteoldrdn: 0 newsuperior: ou=Accounting,dc=airius,dc=com EOL end def test_modrdn_record ldif_source = <<-EOL version: 1 # Modify an entry's relative distinguished name dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com changetype: modrdn newrdn: cn=Paula Jensen deleteoldrdn: 1 EOL change_attributes = { "dn" => "cn=Paul Jensen,ou=Product Development,dc=airius,dc=com", } ldif = assert_ldif(1, [change_attributes], ldif_source) record = ldif.records[0] assert_equal("modrdn", record.change_type) assert_true(record.modify_rdn?) assert_equal("cn=Paula Jensen", record.new_rdn) assert_true(record.delete_old_rdn?) assert_nil(record.new_superior) end def test_modrdn_record_to_s ldif_source = <<-EOL version: 1 # Modify an entry's relative distinguished name dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com changetype: modrdn newrdn: cn=Paula Jensen deleteoldrdn: 1 EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Paul Jensen,ou=Product Development,dc=airius,dc=com changetype: modrdn newrdn: cn=Paula Jensen deleteoldrdn: 1 EOL end def test_moddn_record_with_newsuperior ldif_source = <<-EOL version: 1 # Rename an entry and move all of its children to a new location in # the directory tree (only implemented by LDAPv3 servers). dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: ou=Product Development Accountants deleteoldrdn: 0 newsuperior: ou=Accounting, dc=airius, dc=com EOL change_attributes = { "dn" => "ou=PD Accountants,ou=Product Development,dc=airius,dc=com", } ldif = assert_ldif(1, [change_attributes], ldif_source) record = ldif.records[0] assert_equal("moddn", record.change_type) assert_true(record.modify_dn?) assert_equal("ou=Product Development Accountants", record.new_rdn) assert_false(record.delete_old_rdn?) assert_equal("ou=Accounting,dc=airius,dc=com", record.new_superior) end def test_moddn_record_with_newsuperior_to_s ldif_source = <<-EOL version: 1 # Rename an entry and move all of its children to a new location in # the directory tree (only implemented by LDAPv3 servers). dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: ou=Product Development Accountants deleteoldrdn: 0 newsuperior: ou=Accounting, dc=airius, dc=com EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: ou=PD Accountants,ou=Product Development,dc=airius,dc=com changetype: moddn newrdn: ou=Product Development Accountants deleteoldrdn: 0 newsuperior: ou=Accounting,dc=airius,dc=com EOL end def test_moddn_record ldif_source = <<-EOL version: 1 # Modify an entry's relative distinguished name dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen deleteoldrdn: 1 EOL change_attributes = { "dn" => "cn=Paul Jensen,ou=Product Development,dc=airius,dc=com", } ldif = assert_ldif(1, [change_attributes], ldif_source) record = ldif.records[0] assert_equal("moddn", record.change_type) assert_true(record.modify_dn?) assert_equal("cn=Paula Jensen", record.new_rdn) assert_true(record.delete_old_rdn?) assert_nil(record.new_superior) end def test_moddn_record_to_s ldif_source = <<-EOL version: 1 # Modify an entry's relative distinguished name dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com changetype: moddn newrdn: cn=Paula Jensen deleteoldrdn: 1 EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Paul Jensen,ou=Product Development,dc=airius,dc=com changetype: moddn newrdn: cn=Paula Jensen deleteoldrdn: 1 EOL end def test_delete_record ldif_source = <<-EOL version: 1 # Delete an existing entry dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com changetype: delete EOL change_attributes = { "dn" => "cn=Robert Jensen,ou=Marketing,dc=airius,dc=com", } ldif = assert_ldif(1, [change_attributes], ldif_source) record = ldif.records[0] assert_equal("delete", record.change_type) assert_true(record.delete?) end def test_delete_record_to_s ldif_source = <<-EOL version: 1 # Delete an existing entry dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com changetype: delete EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Robert Jensen,ou=Marketing,dc=airius,dc=com changetype: delete EOL end def test_add_record ldif_source = <<-EOL version: 1 # Add a new entry dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com changetype: add objectclass: top objectclass: person objectclass: organizationalPerson cn: Fiona Jensen sn: Jensen uid: fiona telephonenumber: +1 408 555 1212 EOL change_attributes = { "dn" => "cn=Fiona Jensen,ou=Marketing,dc=airius,dc=com", "objectclass" => ["top", "person", "organizationalPerson"], "cn" => ["Fiona Jensen"], "sn" => ["Jensen"], "uid" => ["fiona"], "telephonenumber" => ["+1 408 555 1212"], } ldif = assert_ldif(1, [change_attributes], ldif_source) record = ldif.records[0] assert_equal("add", record.change_type) assert_true(record.add?) end def test_add_record_to_s ldif_source = <<-EOL version: 1 # Add a new entry dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com changetype: add objectclass: top objectclass: person objectclass: organizationalPerson cn: Fiona Jensen sn: Jensen uid: fiona telephonenumber: +1 408 555 1212 EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Fiona Jensen,ou=Marketing,dc=airius,dc=com changetype: add cn: Fiona Jensen objectclass: organizationalPerson objectclass: person objectclass: top sn: Jensen telephonenumber: +1 408 555 1212 uid: fiona EOL end def test_records_with_external_file_reference ldif_source = <<-EOL version: 1 dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Horatio Jensen cn: Horatio N Jensen sn: Jensen uid: hjensen telephonenumber: +1 408 555 1212 jpegphoto:< file://#{jpeg_photo_path} EOL record = { "dn" => "cn=Horatio Jensen,ou=Product Testing,dc=airius,dc=com", "objectclass" => ["top", "person", "organizationalPerson"], "cn" => ["Horatio Jensen", "Horatio N Jensen"], "sn" => ["Jensen"], "uid" => ["hjensen"], "telephonenumber" => ["+1 408 555 1212"], "jpegphoto" => [jpeg_photo], } assert_ldif(1, [record], ldif_source) end def test_records_with_external_file_reference_to_s ldif_source = <<-EOL version: 1 dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Horatio Jensen cn: Horatio N Jensen sn: Jensen uid: hjensen telephonenumber: +1 408 555 1212 jpegphoto:< file://#{jpeg_photo_path} EOL set_encoding(ldif_source, "utf-8") jpeg_photo_attribute = "jpegphoto:: " value = [jpeg_photo].pack("m").gsub(/\n/, '') first_line_value_size = 75 - jpeg_photo_attribute.size jpeg_photo_attribute << value[0, first_line_value_size] + "\n" value = value[first_line_value_size..-1] value.scan(/.{1,74}/).each do |line| jpeg_photo_attribute << " #{line}\n" end jpeg_photo_attribute = jpeg_photo_attribute.chomp assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Horatio Jensen,ou=Product Testing,dc=airius,dc=com cn: Horatio Jensen cn: Horatio N Jensen #{jpeg_photo_attribute} objectclass: organizationalPerson objectclass: person objectclass: top sn: Jensen telephonenumber: +1 408 555 1212 uid: hjensen EOL end def test_record_with_external_file_reference_is_invalid ldif_source = <<-EOL version: 1 dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Horatio Jensen sn: Jensen uid: hjensen jpegphoto:< INVALID_URI EOL ldif_source_with_error_mark = <<-EOL jpegphoto:< |@|INVALID_URI EOL assert_invalid_ldif("URI is missing", ldif_source, 9, 13, ldif_source_with_error_mark) end def test_records_with_option_attributes ldif_source = <<-EOL version: 1 dn:: b3U95Za25qWt6YOoLG89QWlyaXVz # dn:: ou=,o=Airius objectclass: top objectclass: organizationalUnit ou:: 5Za25qWt6YOo # ou:: ou;lang-ja:: 5Za25qWt6YOo # ou;lang-ja:: ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2 # ou;lang-ja:: ou;lang-en: Sales description: Japanese office dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz # dn:: uid=,ou=,o=Airius userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM= objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson uid: rogasawara mail: rogasawara@airius.co.jp givenname;lang-ja:: 44Ot44OJ44OL44O8 # givenname;lang-ja:: sn;lang-ja:: 5bCP56yg5Y6f # sn;lang-ja:: cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA== # cn;lang-ja:: title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw== # title;lang-ja:: preferredlanguage: ja givenname:: 44Ot44OJ44OL44O8 # givenname:: sn:: 5bCP56yg5Y6f # sn:: cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA== # cn:: title:: 5Za25qWt6YOoIOmDqOmVtw== # title:: givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8 # givenname;lang-ja;phonetic:: sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ # sn;lang-ja;phonetic:: cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA== # cn;lang-ja;phonetic:: title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg== # title;lang-ja;phonetic:: # givenname;lang-en: Rodney sn;lang-en: Ogasawara cn;lang-en: Rodney Ogasawara title;lang-en: Sales, Director EOL set_encoding(ldif_source, "utf-8") record1 = { "dn" => "ou=営業部,o=Airius", "objectclass" => ["top", "organizationalUnit"], "ou" => [ "営業部", {"lang-ja" => [ "営業部", {"phonetic" => ["えいぎょうぶ"]}, ], }, {"lang-en" => ["Sales"]}, ], "description" => ["Japanese office"], } record2 = { "dn" => "uid=rogasawara,ou=営業部,o=Airius", "userpassword" => ["{SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM="], "objectclass" => ["top", "person", "organizationalPerson", "inetOrgPerson"], "uid" => ["rogasawara"], "mail" => ["rogasawara@airius.co.jp"], "givenname" => [ {"lang-ja" => [ "ロドニー", {"phonetic" => ["ろどにー"]}, ] }, "ロドニー", {"lang-en" => ["Rodney"]}, ], "sn" => [ {"lang-ja" => [ "小笠原", {"phonetic" => ["おがさわら"]}, ] }, "小笠原", {"lang-en" => ["Ogasawara"]}, ], "cn" => [ {"lang-ja" => [ "小笠原 ロドニー", {"phonetic" => ["おがさわら ろどにー"]}, ], }, "小笠原 ロドニー", {"lang-en" => ["Rodney Ogasawara"]}, ], "title" => [ {"lang-ja" => [ "営業部 部長", {"phonetic" => ["えいぎょうぶ ぶちょう"]} ] }, "営業部 部長", {"lang-en" => ["Sales, Director"]}, ], "preferredlanguage" => ["ja"], } assert_ldif(1, [record1, record2], ldif_source) end def test_records_with_option_attributes_to_s ldif_source = <<-EOL version: 1 dn:: b3U95Za25qWt6YOoLG89QWlyaXVz # dn:: ou=,o=Airius objectclass: top objectclass: organizationalUnit ou:: 5Za25qWt6YOo # ou:: ou;lang-ja:: 5Za25qWt6YOo # ou;lang-ja:: ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2 # ou;lang-ja:: ou;lang-en: Sales description: Japanese office dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz # dn:: uid=,ou=,o=Airius userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM= objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson uid: rogasawara mail: rogasawara@airius.co.jp givenname;lang-ja:: 44Ot44OJ44OL44O8 # givenname;lang-ja:: sn;lang-ja:: 5bCP56yg5Y6f # sn;lang-ja:: cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA== # cn;lang-ja:: title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw== # title;lang-ja:: preferredlanguage: ja givenname:: 44Ot44OJ44OL44O8 # givenname:: sn:: 5bCP56yg5Y6f # sn:: cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA== # cn:: title:: 5Za25qWt6YOoIOmDqOmVtw== # title:: givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8 # givenname;lang-ja;phonetic:: sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ # sn;lang-ja;phonetic:: cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA== # cn;lang-ja;phonetic:: title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg== # title;lang-ja;phonetic:: # givenname;lang-en: Rodney sn;lang-en: Ogasawara cn;lang-en: Rodney Ogasawara title;lang-en: Sales, Director EOL set_encoding(ldif_source, "utf-8") assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn:: b3U95Za25qWt6YOoLG89QWlyaXVz description: Japanese office objectclass: organizationalUnit objectclass: top ou:: 5Za25qWt6YOo ou;lang-en: Sales ou;lang-ja:: 5Za25qWt6YOo ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2 dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA== cn;lang-en: Rodney Ogasawara cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA== cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA== givenname:: 44Ot44OJ44OL44O8 givenname;lang-en: Rodney givenname;lang-ja:: 44Ot44OJ44OL44O8 givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8 mail: rogasawara@airius.co.jp objectclass: inetOrgPerson objectclass: organizationalPerson objectclass: person objectclass: top preferredlanguage: ja sn:: 5bCP56yg5Y6f sn;lang-en: Ogasawara sn;lang-ja:: 5bCP56yg5Y6f sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ title:: 5Za25qWt6YOoIOmDqOmVtw== title;lang-en: Sales, Director title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw== title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg== uid: rogasawara userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM= EOL end def test_an_record_with_base64_encoded_value ldif_source = <<-EOL version: 1 dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Gern Jensen cn: Gern O Jensen sn: Jensen uid: gernj telephonenumber: +1 408 555 1212 description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVl IGlzIGJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdG VyIGluIGl0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQg b3V0IG1vcmUu EOL record = { "dn" => "cn=Gern Jensen,ou=Product Testing,dc=airius,dc=com", "objectclass" => ["top", "person", "organizationalPerson"], "cn" => ["Gern Jensen", "Gern O Jensen"], "sn" => ["Jensen"], "uid" => ["gernj"], "telephonenumber" => ["+1 408 555 1212"], "description" => ["What a careful reader you are! " + "This value is base-64-encoded because it has a " + "control character in it (a CR).\r By the way, " + "you should really get out more."], } assert_ldif(1, [record], ldif_source) end def test_an_record_with_base64_encoded_value_to_s ldif_source = <<-EOL version: 1 dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Gern Jensen cn: Gern O Jensen sn: Jensen uid: gernj telephonenumber: +1 408 555 1212 description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVl IGlzIGJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdG VyIGluIGl0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQg b3V0IG1vcmUu EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Gern Jensen,ou=Product Testing,dc=airius,dc=com cn: Gern Jensen cn: Gern O Jensen description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVlIGlzI GJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdGVyIGluIGl 0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQgb3V0IG1vcmUu objectclass: organizationalPerson objectclass: person objectclass: top sn: Jensen telephonenumber: +1 408 555 1212 uid: gernj EOL end def test_an_record_with_folded_attribute_value ldif_source = <<-EOL version: 1 dn:cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com objectclass:top objectclass:person objectclass:organizationalPerson cn:Barbara Jensen cn:Barbara J Jensen cn:Babs Jensen sn:Jensen uid:bjensen telephonenumber:+1 408 555 1212 description:Babs is a big sailing fan, and travels extensively in sea rch of perfect sailing conditions. title:Product Manager, Rod and Reel Division EOL record = { "dn" => "cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com", "objectclass" => ["top", "person", "organizationalPerson"], "cn" => ["Barbara Jensen", "Barbara J Jensen", "Babs Jensen"], "sn" => ["Jensen"], "uid" => ["bjensen"], "telephonenumber" => ["+1 408 555 1212"], "description" => ["Babs is a big sailing fan, and travels extensively " + "in search of perfect sailing conditions."], "title" => ["Product Manager, Rod and Reel Division"], } assert_ldif(1, [record], ldif_source) end def test_an_record_with_folded_attribute_value_to_s ldif_source = <<-EOL version: 1 dn:cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com objectclass:top objectclass:person objectclass:organizationalPerson cn:Barbara Jensen cn:Barbara J Jensen cn:Babs Jensen sn:Jensen uid:bjensen telephonenumber:+1 408 555 1212 description:Babs is a big sailing fan, and travels extensively in sea rch of perfect sailing conditions. title:Product Manager, Rod and Reel Division EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com cn: Babs Jensen cn: Barbara J Jensen cn: Barbara Jensen description: Babs is a big sailing fan, and travels extensively in search o f perfect sailing conditions. objectclass: organizationalPerson objectclass: person objectclass: top sn: Jensen telephonenumber: +1 408 555 1212 title: Product Manager, Rod and Reel Division uid: bjensen EOL end def test_records ldif_source = <<-EOL version: 1 dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Barbara Jensen cn: Barbara J Jensen cn: Babs Jensen sn: Jensen uid: bjensen telephonenumber: +1 408 555 1212 description: A big sailing fan. dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Bjorn Jensen sn: Jensen telephonenumber: +1 408 555 1212 EOL record1 = { "dn" => "cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com", "objectclass" => ["top", "person", "organizationalPerson"], "cn" => ["Barbara Jensen", "Barbara J Jensen", "Babs Jensen"], "sn" => ["Jensen"], "uid" => ["bjensen"], "telephonenumber" => ["+1 408 555 1212"], "description" => ["A big sailing fan."], } record2 = { "dn" => "cn=Bjorn Jensen,ou=Accounting,dc=airius,dc=com", "objectclass" => ["top", "person", "organizationalPerson"], "cn" => ["Bjorn Jensen"], "sn" => ["Jensen"], "telephonenumber" => ["+1 408 555 1212"], } assert_ldif(1, [record1, record2], ldif_source) end def test_records_to_s ldif_source = <<-EOL version: 1 dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Barbara Jensen cn: Barbara J Jensen cn: Babs Jensen sn: Jensen uid: bjensen telephonenumber: +1 408 555 1212 description: A big sailing fan. dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Bjorn Jensen sn: Jensen telephonenumber: +1 408 555 1212 EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com cn: Babs Jensen cn: Barbara J Jensen cn: Barbara Jensen description: A big sailing fan. objectclass: organizationalPerson objectclass: person objectclass: top sn: Jensen telephonenumber: +1 408 555 1212 uid: bjensen dn: cn=Bjorn Jensen,ou=Accounting,dc=airius,dc=com cn: Bjorn Jensen objectclass: organizationalPerson objectclass: person objectclass: top sn: Jensen telephonenumber: +1 408 555 1212 EOL end def test_an_record ldif_source = <<-EOL version: 1 dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Barbara Jensen cn: Barbara J Jensen cn: Babs Jensen sn: Jensen uid: bjensen telephonenumber: +1 408 555 1212 description: A big sailing fan. EOL record = { "dn" => "cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com", "objectclass" => ["top", "person", "organizationalPerson"], "cn" => ["Barbara Jensen", "Barbara J Jensen", "Babs Jensen"], "sn" => ["Jensen"], "uid" => ["bjensen"], "telephonenumber" => ["+1 408 555 1212"], "description" => ["A big sailing fan."], } assert_ldif(1, [record], ldif_source) end def test_an_record_to_s ldif_source = <<-EOL version: 1 dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com objectclass: top objectclass: person objectclass: organizationalPerson cn: Barbara Jensen cn: Barbara J Jensen cn: Babs Jensen sn: Jensen uid: bjensen telephonenumber: +1 408 555 1212 description: A big sailing fan. EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com cn: Babs Jensen cn: Barbara J Jensen cn: Barbara Jensen description: A big sailing fan. objectclass: organizationalPerson objectclass: person objectclass: top sn: Jensen telephonenumber: +1 408 555 1212 uid: bjensen EOL end def test_comment ldif_source = <<-EOL version: 1 dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com objectclass: top # objectclass: person #objectcl ass: organizationalPerson EOL record = { "dn" => "cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com", "objectclass" => ["top"], } assert_ldif(1, [record], ldif_source) end def test_comment_to_s ldif_source = <<-EOL version: 1 dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com objectclass: top # objectclass: person #objectcl ass: organizationalPerson EOL assert_ldif_to_s(<<-EOL, ldif_source) version: 1 dn: cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com objectclass: top EOL end def test_dn_spec assert_invalid_ldif("'dn:' is missing", "version: 1\n", 2, 1, "version: 1\n|@|") assert_invalid_ldif("DN is missing", "version: 1\ndn:", 2, 4, "dn:|@|") assert_invalid_ldif("DN is missing", "version: 1\ndn::", 2, 5, "dn::|@|") assert_invalid_ldif("DN is missing", "version: 1\ndn:\n", 2, 4, "dn:|@|\n") assert_invalid_ldif("DN is missing", "version: 1\ndn: \n", 2, 5, "dn: |@|\n") dn = "cn=Barbara Jensen,ou=Product Development,dc=example,dc=com" cn = "Barbara Jensen" assert_valid_dn(dn, "version: 1\ndn: #{dn}\ncn:#{cn}\n") encoded_dn = Base64.encode64(dn).gsub(/\n/, "\n ") encoded_cn = Base64.encode64(cn).gsub(/\n/, "\n ") assert_valid_dn(dn, "version: 1\ndn:: #{encoded_dn}\ncn::#{encoded_cn}\n") end def test_version_number assert_valid_version(1, "version: 1\ndn: dc=com\ndc: com") assert_valid_version(1, "version: 1\r\ndn: dc=com\ndc: com\n") assert_valid_version(1, "version: 1\r\n\n\r\n\ndn: dc=com\ndc: com\n") assert_invalid_ldif(["unsupported version: %d", 0], "version: 0", 1, 11, "version: 0|@|") assert_invalid_ldif(["unsupported version: %d", 2], "version: 2", 1, 11, "version: 2|@|") assert_invalid_ldif("separator is missing", "version: 1", 1, 11, "version: 1|@|") end def test_version_spec assert_invalid_ldif("version spec is missing", "", 1, 1, "|@|") assert_invalid_ldif("version spec is missing", "VERSION: 1", 1, 1, "|@|VERSION: 1") assert_invalid_ldif("version number is missing", "version:", 1, 9, "version:|@|") assert_invalid_ldif("version number is missing", "version: ", 1, 10, "version: |@|") assert_invalid_ldif("version number is missing", "version: XXX", 1, 10, "version: |@|XXX") end private def assert_ldif(version, records, ldif_source) encoding = ldif_source.encoding if ldif_source.respond_to?(:encoding) ldif = ActiveLdap::Ldif.parse(ldif_source) assert_equal(version, ldif.version) assert_equal(records, ldif.records.collect {|record| record.to_hash}) regenerated_ldif = ldif.to_s set_encoding(regenerated_ldif, encoding) reparsed_ldif = ActiveLdap::Ldif.parse(regenerated_ldif) assert_equal(ldif, reparsed_ldif) ldif end def assert_valid_dn(dn, ldif_source) ldif = ActiveLdap::Ldif.parse(ldif_source) assert_equal([dn], ldif.records.collect {|record| record.dn}) end def assert_valid_version(version, ldif_source) ldif = ActiveLdap::Ldif.parse(ldif_source) assert_equal(version, ldif.version) end def assert_invalid_ldif(reason, ldif, line, column, nearest) exception = assert_raise(ActiveLdap::LdifInvalid) do ActiveLdap::Ldif.parse(ldif) end reason, *params = reason params = params.collect {|param| param.is_a?(String) ? _(param) : param} assert_equal([_(reason) % params, line, column, nearest, ldif], [exception.reason, exception.line, exception.column, exception.nearest, exception.ldif]) end def assert_ldif_to_s(expected_ldif_source, original_ldif_source) ldif = ActiveLdap::Ldif.parse(original_ldif_source) assert_equal(expected_ldif_source, ldif.to_s) end def set_encoding(string, encoding) string.force_encoding("utf-8") if string.respond_to?(:force_encoding) end end activeldap-5.2.4/test/test_syntax.rb0000644000004100000410000003454213464071751017577 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestSyntax < Test::Unit::TestCase include AlTestUtils include ActiveLdap::Helper SYNTAXES = \ [ "( 1.3.6.1.1.16.1 DESC 'UUID' )", "( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )", "( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )", "( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )", "( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )", "( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' " + "X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )", "( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' )", "( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )", "( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )", "( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )", "( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )", "( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", "( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )", "( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )", "( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' X-NOT-HUMAN-READABLE 'TRUE' )", "( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )", "( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )", "( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )", "( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )", "( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )", "( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )", "( 1.2.36.79672281.1.5.0 DESC 'RDN' )", "( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )", "( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )", "( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' " + "X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )", "( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' " + "X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )", "( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' " + "X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )", "( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )", "( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )", "( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' X-NOT-HUMAN-READABLE 'TRUE' )", "( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' X-NOT-HUMAN-READABLE 'TRUE' )" ] def setup @schema = ActiveLdap::Schema.new("ldapSyntaxes" => SYNTAXES.dup) @syntaxes = {} @schema.ldap_syntaxes.each do |syntax| @syntaxes[syntax.description] = syntax end end def teardown end priority :must def test_id_with_length id = "1.3.6.1.4.1.1466.115.121.1.26" syntax = ActiveLdap::Schema::Syntax.new(id, @schema) assert_equal([id, nil], [syntax.id, syntax.length]) syntax = ActiveLdap::Schema::Syntax.new("#{id}{128}", @schema) assert_equal([id, 128], [syntax.id, syntax.length]) end priority :normal def test_bit_string_type_cast assert_type_cast_without_validation(nil, nil, 'Bit String') assert_type_cast("0101111101", "'0101111101'B", 'Bit String') end def test_boolean_type_cast assert_type_cast_without_validation(nil, nil, 'Boolean') assert_type_cast(true, "TRUE", "Boolean") assert_type_cast(false, "FALSE", "Boolean") end def test_boolean_normalize_value assert_normalize_value("TRUE", true, 'Boolean') assert_normalize_value("TRUE", "1", 'Boolean') assert_normalize_value("FALSE", false, 'Boolean') assert_normalize_value("FALSE", "0", 'Boolean') end def test_dn_type_cast assert_type_cast_without_validation(nil, nil, 'Distinguished Name') assert_dn_type_cast("cn=test", 'Distinguished Name') end class TestGeneralizedTime < self private def syntax_name "Generalized Time" end class TestTypeCast < self def test_nil assert_type_cast_without_validation(nil, nil, syntax_name) end def test_timezone_none assert_type_cast(Time.parse("1994/12/16 10:32:12"), "19941216103212") end def test_timezone_Z assert_type_cast(Time.parse("1994/12/16 10:32:12Z"), "19941216103212Z") end def test_timezone_difference assert_type_cast(Time.parse("1994/12/16 10:32:12.345 +09:00"), "19941216103212.345+0900") end def test_timezone_difference_with_minutes assert_type_cast(Time.parse("2019-02-13 15:54:23 +0530"), "20190213155423+0530") end def test_year_month_day_hour_minute assert_type_cast(Time.parse("2008/01/07 03:46:00"), "200801070346") end def test_before_posix_time time_can_handle_before_posix_time = false begin Time.utc(1601) time_can_handle_before_posix_time = true rescue ArgumentError end if time_can_handle_before_posix_time assert_type_cast(Time.utc(1601, 1, 1, 0, 4, 17), "16010101000417.0Z") else assert_type_cast(Time.at(0), "16010101000417.0Z") end end private def assert_type_cast(type_casted_value, original_value) super(type_casted_value, original_value, syntax_name) end end class TestValidate < self class TestValid < self def test_no_timezone assert_valid("19941216103201") end def test_timezone_Z assert_valid("19941216103212Z") end def test_timezone_difference assert_valid("19941216103230+0900") end def test_fraction_separator_period assert_valid("20080107034615.0Z") end def test_fraction_separator_comma assert_valid("20080107034615,123-0900") end def test_year_month_day_hour_minute assert_valid("199412161032") end private def assert_valid(value) super(value, syntax_name) end end class TestInvalid < self def test_year_only value = "1994" params = [value.inspect, %w(month day hour minute).join(", ")] assert_invalid(_("%s has missing components: %s") % params, value) end def test_year_month_day_hour_only value = "1994121610" params = [value.inspect, %w(minute).join(", ")] assert_invalid(_("%s has missing components: %s") % params, value) end private def assert_invalid(reason, value) super(reason, value, syntax_name) end end end end def test_integer_type_cast assert_type_cast_without_validation(nil, nil, "Integer") assert_type_cast(1321, "1321", "Integer") end def test_bit_string_validate assert_valid("'0101111101'B", 'Bit String') assert_valid("''B", 'Bit String') value = "0101111101'B" assert_invalid(_("%s doesn't have the first \"'\"") % value.inspect, value, 'Bit String') value = "'0101111101'" assert_invalid(_("%s doesn't have the last \"'B\"") % value.inspect, value, 'Bit String') value = "'0101111101B" assert_invalid(_("%s doesn't have the last \"'B\"") % value.inspect, value, 'Bit String') value = "'0A'B" assert_invalid(_("%s has invalid character '%s'") % [value.inspect, "A"], value, 'Bit String') end def test_boolean_validate assert_valid("TRUE", "Boolean") assert_valid("FALSE", "Boolean") value = "true" assert_invalid(_("%s should be TRUE or FALSE") % value.inspect, value, "Boolean") end def test_country_string_validate assert_valid("ja", "Country String") assert_valid("JA", "Country String") value = "japan" assert_invalid(_("%s should be just 2 printable characters") % value.inspect, value, "Country String") end def test_dn_validate assert_valid("cn=test", 'Distinguished Name') assert_valid("CN=Steve Kille,O=Isode Limited,C=GB", 'Distinguished Name') assert_valid("OU=Sales+CN=J. Smith,O=Widget Inc.,C=US", 'Distinguished Name') assert_valid("CN=L. Eagle,O=Sue\\, Grabbit and Runn,C=GB", 'Distinguished Name') assert_valid("CN=Before\\0DAfter,O=Test,C=GB", 'Distinguished Name') assert_valid("1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB", 'Distinguished Name') assert_valid("SN=Lu\\C4\\8Di\\C4\\87", 'Distinguished Name') value = "test" params = [value, _("attribute value is missing")] assert_invalid(_('%s is invalid distinguished name (DN): %s') % params, value, 'Distinguished Name') end def test_directory_string_validate assert_valid("This is a string of DirectoryString containing \#!%\#@", "Directory String") assert_valid("これはDirectoryString文字列です。", "Directory String") value = "これはDirectoryString文字列です。" if value.respond_to?(:encode) value = value.encode("euc-jp") else value = NKF.nkf("-We", value) end assert_invalid(_("%s has invalid UTF-8 character") % value.inspect, value, "Directory String") end def test_integer_validate assert_valid("1321", "Integer") assert_invalid_integer("13.5") assert_invalid_integer("string") end def test_jpeg_validate assert_valid([0xffd8].pack("n"), "JPEG") assert_invalid(_("invalid JPEG format"), "", "JPEG") assert_invalid(_("invalid JPEG format"), "jpeg", "JPEG") end def test_name_and_optional_uid_validate assert_valid("1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB#'0101'B", "Name And Optional UID") assert_valid("cn=test", "Name And Optional UID") value = "test" params = [value, _("attribute value is missing")] assert_invalid(_('%s is invalid distinguished name (DN): %s') % params, value, "Name And Optional UID") bit_string = "'00x'B" params = [bit_string.inspect, "x"] assert_invalid(_("%s has invalid character '%s'") % params, "cn=test\##{bit_string}", "Name And Optional UID") end def test_numeric_string_validate assert_valid("1997", "Numeric String") assert_invalid_numeric_string("-3") assert_invalid_numeric_string("-3.5") assert_invalid_numeric_string("string") end def test_oid_validate assert_valid("1.2.3.4", "OID") assert_valid("cn", "OID") assert_invalid_oid("\#@!", "attribute type is missing") end def test_other_mailbox_validate assert_valid("smtp$bob@example.com", "Other Mailbox") value = "smtp" assert_invalid(_("%s has no mailbox") % value.inspect, value, "Other Mailbox") value = "smtp$" assert_invalid(_("%s has no mailbox") % value.inspect, value, "Other Mailbox") value = "$bob@example.com" assert_invalid(_("%s has no mailbox type") % value.inspect, value, "Other Mailbox") value = "!$bob@example.com" params = [value.inspect, "!"] reason = _("%s has unprintable character in mailbox type: '%s'") % params assert_invalid(reason, value, "Other Mailbox") end def test_postal_address_validate assert_valid("1234 Main St.$Anytown, CA 12345$USA", "Postal Address") assert_valid("\\241,000,000 Sweepstakes$PO Box 1000000$Anytown, " + "CA 12345$USA", "Postal Address") assert_valid("$", "Postal Address") assert_valid("1234 Main St.$", "Postal Address") assert_invalid(_("empty string"), "", "Postal Address") value = "東京" if value.respond_to?(:encode) value = value.encode("euc-jp") else value = NKF.nkf("-We", value) end assert_invalid(_("%s has invalid UTF-8 character") % value.inspect, value, "Postal Address") end def test_printable_string_validate assert_valid("This is a PrintableString", "Printable String") assert_invalid(_("empty string"), "", "Printable String") value = "abc!def" params = [value.inspect, "!"] reason = _("%s has unprintable character: '%s'") % params assert_invalid(reason, value, "Printable String") value = "abcあdef" params = [value.inspect, "あ"] reason = _("%s has unprintable character: '%s'") % params assert_invalid(reason, value, "Printable String") end def test_telephone_number_validate assert_valid("+1 512 305 0280", "Telephone Number") assert_valid("", "Telephone Number") value = "+1 5!2 305 0280" params = [value.inspect, "!"] reason = _("%s has unprintable character: '%s'") % params assert_invalid(reason, value, "Telephone Number") end private def assert_valid(value, syntax_name) assert_nil(@syntaxes[syntax_name].validate(value)) end def assert_invalid(reason, value, syntax_name) assert_equal(reason, @syntaxes[syntax_name].validate(value)) end def assert_invalid_integer(value) assert_invalid(_("%s is invalid integer format") % value.inspect, value, "Integer") end def assert_invalid_numeric_string(value) assert_invalid(_("%s is invalid numeric format") % value.inspect, value, "Numeric String") end def assert_invalid_oid(value, reason=nil) if reason message = _("%s is invalid OID format: %s") % [value.inspect, _(reason)] else message = _("%s is invalid OID format") % value.inspect end assert_invalid(message, value, "OID") end def assert_type_cast_without_validation(type_casted_value, original_value, syntax_name) syntax = @syntaxes[syntax_name] assert_equal(type_casted_value, syntax.type_cast(original_value)) assert_equal(type_casted_value, syntax.type_cast(type_casted_value)) end def assert_type_cast(type_casted_value, original_value, syntax_name) assert_type_cast_without_validation(type_casted_value, original_value, syntax_name) assert_valid(type_casted_value, syntax_name) end def assert_dn_type_cast(original_value, syntax_name) assert_type_cast(ActiveLdap::DN.parse(original_value), original_value, syntax_name) end def assert_normalize_value(normalized_value, original_value, syntax_name) syntax = @syntaxes[syntax_name] assert_equal(normalized_value, syntax.normalize_value(original_value)) end end activeldap-5.2.4/test/test_useradd-binary.rb0000644000004100000410000000364613464071751021163 0ustar www-datawww-datarequire 'al-test-utils' class TestUseraddBinary < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "useradd-binary") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_exist_user make_temporary_user do |user, password| assert(@user_class.exists?(user.uid)) assert_equal([false, "User #{user.uid} already exists.\n"], run_command(user.uid, user.cn, user.uid_number)) assert(@user_class.exists?(user.uid)) end end def test_add_user ensure_delete_user("test-user") do |uid,| assert_useradd_binary_successfully(uid, uid, 10000) end end private def assert_useradd_binary_successfully(name, cn, uid, *args, &block) _wrap_assertion do assert(!@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([true, ""], run_command(*args, &block)) assert(@user_class.exists?(name)) user = @user_class.find(name) assert_equal(name, user.uid) assert_equal(cn, user.cn) assert_equal(uid.to_i, user.uid_number) assert_equal(uid.to_i, user.gid_number) assert_equal(uid.to_s, user.uid_number_before_type_cast) assert_equal(uid.to_s, user.gid_number_before_type_cast) assert_equal(['person', 'posixAccount', 'shadowAccount', 'strongAuthenticationUser'].sort, user.classes.sort) cert = File.read(File.join(@examples_dir, 'example.der')) cert.force_encoding('ascii-8bit') if cert.respond_to?(:force_encoding) assert_equal(cert, user.user_certificate) end end def assert_useradd_binary_failed(name, cn, uid, message, *args, &block) _wrap_assertion do assert(!@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([false, message], run_command(*args, &block)) assert(!@user_class.exists?(name)) end end end activeldap-5.2.4/test/test_user.rb0000644000004100000410000001606213464071751017224 0ustar www-datawww-datarequire 'al-test-utils' class TestUser < Test::Unit::TestCase include AlTestUtils # This adds all required attributes and writes def test_add ensure_delete_user("test-user") do |uid| user = @user_class.new(uid) assert(user.new_entry?, "#{uid} must not exist in LDAP prior to testing") assert_equal(['posixAccount', 'person'].sort, user.classes.sort, "Class User's ldap_mapping should specify " + "['posixAccount', 'person']. This was not returned.") user.add_class('posixAccount', 'shadowAccount', 'person', 'inetOrgPerson', 'organizationalPerson') cn = 'Test User (Default Language)' user.cn = cn assert_equal(cn, user.cn, 'user.cn should have returned "#{cn}"') # test force_array assert_equal([cn], user.cn(true), 'user.cn(true) should have returned "[#{cn}]"') cn = {'lang-en-us' => 'Test User (EN-US Language)'} user.cn = cn # Test subtypes assert_equal(cn, user.cn, 'user.cn should match') cn = ['Test User (Default Language)', {'lang-en-us' => ['Test User (EN-US Language)', 'Foo']}] user.cn = cn # Test multiple entries with subtypes assert_equal(cn, user.cn, 'This should have returned an array of a ' + 'normal cn and a lang-en-us cn.') uid_number = "9000" user.uid_number = uid_number assert_equal(uid_number.to_i, user.uid_number) assert_equal(uid_number, user.uid_number_before_type_cast) gid_number = 9000 user.gid_number = gid_number assert_equal(gid_number, user.gid_number) assert_equal(gid_number, user.gid_number_before_type_cast) home_directory = '/home/foo' user.home_directory = home_directory # just for sanity's sake assert_equal(home_directory, user.home_directory, 'This should be #{home_directory.dump}.') assert_equal([home_directory], user.home_directory(true), 'This should be [#{home_directory.dump}].') see_also = "cn=XXX,dc=local,dc=net" user.see_also = see_also assert_equal(ActiveLdap::DN.parse(see_also), user.see_also) see_also = ActiveLdap::DN.parse(see_also) user.see_also = see_also assert_equal(see_also, user.see_also) assert(!user.valid?) assert(user.errors[:sn].any?) errors = %w(person organizationalPerson inetOrgPerson).collect do |object_class| if ActiveLdap.get_text_supported? format = _("is required attribute by objectClass '%s': " \ "aliases: %s") format = user._(format) format % [user.class.human_object_class_name(object_class), user.class.human_attribute_name("surname")] else format = "is required attribute by objectClass '%s': aliases: %s" user._(format) % [object_class, "surname"] end end assert_equal(errors.sort, user.errors[:sn].sort) user.sn = ['User'] assert(user.valid?) assert_equal(0, user.errors.size) assert_nothing_raised {user.save!} user.user_certificate = certificate user.jpeg_photo = jpeg_photo assert(ActiveLdap::Base.schema.attribute('jpegPhoto').binary?, 'jpegPhoto is binary?') assert(ActiveLdap::Base.schema.attribute('userCertificate').binary?, 'userCertificate is binary?') assert_nothing_raised {user.save!} end end # This tests the reload of a binary_required type def test_binary_required require 'openssl' make_temporary_user do |user, password| # validate add user.user_certificate = nil assert_nil(user.user_certificate) assert_nothing_raised() { user.save! } assert_nil(user.user_certificate) user.user_certificate = {"binary" => [certificate]} assert_equal(certificate, user.user_certificate) assert_nothing_raised() { user.save! } assert_equal(certificate, user.user_certificate) # now test modify user.user_certificate = nil assert_nil(user.user_certificate) assert_nothing_raised() { user.save! } assert_nil(user.user_certificate) user.user_certificate = certificate assert_equal(certificate, user.user_certificate) assert_nothing_raised() { user.save! } # validate modify user = @user_class.find(user.uid) assert_equal(certificate, user.user_certificate) expected_cert = OpenSSL::X509::Certificate.new(certificate) actual_cert = user.user_certificate actual_cert = OpenSSL::X509::Certificate.new(actual_cert) assert_equal(expected_cert.subject.to_s, actual_cert.subject.to_s, 'Cert must parse correctly still') end end def test_binary_required_nested make_temporary_user do |user, password| user.user_certificate = {"lang-en" => [certificate]} assert_equal({'lang-en' => certificate}, user.user_certificate) assert_nothing_raised() { user.save! } assert_equal({'lang-en' => certificate}, user.user_certificate) end end # This tests the reload of a binary type (not forced!) def test_binary make_temporary_user do |user, password| # reload and see what happens assert_equal(jpeg_photo, user.jpeg_photo, "This should have been equal to #{jpeg_photo_path.dump}") # now test modify user.jpeg_photo = nil assert_nil(user.jpeg_photo) assert_nothing_raised() { user.save! } assert_nil(user.jpeg_photo) user.jpeg_photo = jpeg_photo assert_equal(jpeg_photo, user.jpeg_photo) assert_nothing_raised() { user.save! } # now validate modify user = @user_class.find(user.uid) assert_equal(jpeg_photo, user.jpeg_photo) end end # This tests the removal of a objectclass def test_remove_object_class make_temporary_user do |user, password| assert_nil(user.shadow_max, 'Should get the default nil value for shadowMax') # Remove shadowAccount user.remove_class('shadowAccount') assert(user.valid?) assert_nothing_raised() { user.save! } assert_raise(NoMethodError, 'shadowMax should not be defined anymore' ) do user.shadow_max end end end # Just modify a few random attributes def test_modify_with_subtypes make_temporary_user do |user, password| cn = ['Test User', {'lang-en-us' => ['Test User', 'wad']}] user.cn = cn assert_nothing_raised() { user.save! } user = @user_class.find(user.uid) assert_equal(cn.sort_by {|value| value.to_s}, user.cn.sort_by {|value| value.to_s}, 'Making sure a modify with mixed subtypes works') end end # This tests some invalid input handling def test_invalid_input end # This tests deletion def test_destroy make_temporary_user do |user, password| user.destroy assert(user.new_entry?, 'user should no longer exist') end end end activeldap-5.2.4/test/test_groupmod.rb0000644000004100000410000000244113464071751020076 0ustar www-datawww-datarequire 'al-test-utils' class TestGroupmod < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "groupmod") end priority :must priority :normal def test_non_exist_group ensure_delete_group("test-group") do |name| assert(!@group_class.exists?(name)) assert_equal([false, "Group #{name} doesn't exist.\n"], run_command(name, 111111)) assert(!@group_class.exists?(name)) end end def test_modify_group make_temporary_group do |group| assert_groupmod_successfully(group.cn, group.gid_number.succ) end end private def assert_groupmod_successfully(name, gid, *args, &block) _wrap_assertion do assert(@group_class.exists?(name)) args.concat([name, gid]) assert_equal([true, ""], run_command(*args, &block)) assert(@group_class.exists?(name)) group = @group_class.find(name) assert_equal(name, group.cn) assert_equal(gid, group.gid_number) end end def assert_groupmod_failed(name, gid, message, *args, &block) _wrap_assertion do assert(@group_class.exists?(name)) args.concat([name, gid]) assert_equal([false, message], run_command(*args, &block)) assert(@group_class.exists?(name)) end end end activeldap-5.2.4/test/test_acts_as_tree.rb0000644000004100000410000000320013464071751020670 0ustar www-datawww-datarequire 'al-test-utils' class TestActsAsTree < Test::Unit::TestCase include AlTestUtils priority :must priority :normal def test_children users = ou_class.find("Users") assert_equal([], users.children.collect(&:ou)) sub_users = users.class.new("SubUsers") users.children << sub_users assert_equal(["SubUsers"], users.children.collect(&:ou)) users = ou_class.find("Users") assert_equal(["SubUsers"], users.children.collect(&:ou)) assert_equal(dn("ou=SubUsers,#{users.dn}"), sub_users.dn) assert(ou_class.exists?("SubUsers")) users.children.replace([]) assert(!ou_class.exists?("SubUsers")) assert_equal([], users.children.collect(&:ou)) end def test_parent users = ou_class.find("Users") assert_equal([], users.children.collect(&:ou)) sub_users = users.class.new("SubUsers") sub_users.parent = users assert_equal(dn("ou=SubUsers,#{users.dn}"), sub_users.dn) assert_equal(["SubUsers"], users.children.collect(&:ou)) sub_users = ou_class.find("SubUsers") assert_equal(users.dn, sub_users.parent.dn) assert_raises(ArgumentError) do sub_users.parent = nil end make_ou("OtherUsers") other_users = ou_class.find("OtherUsers") assert_equal([], other_users.children.collect(&:ou)) sub_users.parent = other_users.dn assert_equal(dn("ou=SubUsers,#{other_users.dn}"), sub_users.dn) other_users.clear_association_cache assert_equal(["SubUsers"], other_users.children.collect(&:ou)) users.clear_association_cache assert_equal([], users.children.collect(&:ou)) end end activeldap-5.2.4/test/test_dirty.rb0000644000004100000410000000453213464071751017400 0ustar www-datawww-datarequire 'al-test-utils' class TestDirty < Test::Unit::TestCase include AlTestUtils priority :must priority :normal def test_clean_after_load make_temporary_user do |user, password| attributes = (user.must + user.may).collect(&:name) - ['objectClass'] _wrap_assertion do attributes.each do |name| assert_false(user.send("#{name}_changed?")) end end end end def test_clean_after_reload make_temporary_user do |user, password| attributes = (user.must + user.may).collect(&:name) - ['objectClass'] user.cn = 'New cn' assert_true(user.cn_changed?) user.reload assert_false(user.cn_changed?) _wrap_assertion do attributes.each do |name| assert_false(user.send("#{name}_changed?")) end end end end def test_setter make_temporary_user do |user, password| attributes = (user.must + user.may).collect(&:name) - ['objectClass', 'cn'] user.cn = 'New cn' assert_true(user.cn_changed?) _wrap_assertion do (attributes - ['cn']).each do |name| assert_false(user.send("#{name}_changed?")) end assert_true(user.cn_changed?) end end end def test_save make_temporary_user do |user, password| attributes = (user.must + user.may).collect(&:name) - ['objectClass', 'cn'] user.cn = 'New cn' assert_true(user.cn_changed?) user.save assert_false(user.cn_changed?) _wrap_assertion do attributes.each do |name| assert_false(user.send("#{name}_changed?")) end end end end def test_save! make_temporary_user do |user, password| attributes = (user.must + user.may).collect(&:name) - ['objectClass', 'cn'] user.cn = 'New cn' assert_true(user.cn_changed?) user.save! assert_false(user.cn_changed?) _wrap_assertion do attributes.each do |name| assert_false(user.send("#{name}_changed?")) end end end end class TestDNChange def test_direct_base_use leaf = ActiveLdap::Base.create leaf.add_class("organizationalUnit") leaf_dn = "ou=addressbook,#{user.dn}" leaf.dn = leaf_dn begin leaf.save ensure ActiveLdap::Base.delete_entry(leaf_dn) if leaf.exists? end end end end activeldap-5.2.4/test/test_usermod-binary-add.rb0000644000004100000410000000402613464071751021731 0ustar www-datawww-datarequire 'al-test-utils' class TestUsermodBinaryAdd < Test::Unit::TestCase include AlTestUtils def setup super @command = File.join(@examples_dir, "usermod-binary-add") make_ou("People") @user_class.prefix = "ou=People" end priority :must priority :normal def test_non_exist_user ensure_delete_user("test-user") do |uid,| assert(!@user_class.exists?(uid)) assert_equal([false, "User #{uid} doesn't exist.\n"], run_command(uid, "New CN", 11111)) assert(!@user_class.exists?(uid)) end end def test_modify_user make_temporary_user do |user, password| assert_usermod_binary_add_successfully(user.uid, "New #{user.cn}", user.uid_number.to_i + 100) end end private def assert_usermod_binary_add_successfully(name, cn, uid, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) previous_classes = @user_class.find(name).classes args.concat([name, cn, uid]) assert_equal([true, ""], run_command(*args, &block)) assert(@user_class.exists?(name)) user = @user_class.find(name) assert_equal(name, user.uid) assert_equal(cn, user.cn) assert_equal(uid.to_i, user.uid_number) assert_equal(uid.to_i, user.gid_number) assert_equal(uid.to_s, user.uid_number_before_type_cast) assert_equal(uid.to_s, user.gid_number_before_type_cast) assert_equal((previous_classes + ['strongAuthenticationUser']).sort, user.classes.sort) cert = File.read(File.join(@examples_dir, 'example.der')) cert.force_encoding("ascii-8bit") if cert.respond_to?(:force_encoding) assert_equal(cert, user.user_certificate) end end def assert_usermod_binary_add_failed(name, cn, uid, message, *args, &block) _wrap_assertion do assert(@user_class.exists?(name)) args.concat([name, cn, uid]) assert_equal([false, message], run_command(*args, &block)) assert(@user_class.exists?(name)) end end end activeldap-5.2.4/test/test_configuration.rb0000644000004100000410000000253513464071751021115 0ustar www-datawww-datarequire 'al-test-utils' class TestConfiguration < Test::Unit::TestCase priority :must priority :normal def test_prepare_configuration_with_silent_uri configuration = { :base => "dc=example,dc=com", :password => "secret", :uri => "ldap://example.com/dc=ignore,dc=me" } prepared_configuration = ActiveLdap::Base.prepare_configuration(configuration) assert_equal({ :host => "example.com", :port => 389, :base => "dc=example,dc=com", :password => "secret", }, prepared_configuration) end def test_prepare_configuration_with_detailed_uri bind_dn = "cn=admin,dc=example,dc=com" configuration = { :host => "example.net", :uri => "ldaps://example.com/dc=example,dc=com??sub??!bindname=#{CGI.escape(bind_dn)}" } prepared_configuration = ActiveLdap::Base.prepare_configuration(configuration) assert_equal({ :host => "example.net", :port => 636, :method => :ssl, :base => "dc=example,dc=com", :scope => "sub", :bind_dn => "cn=admin,dc=example,dc=com", :allow_anonymous => false, }, prepared_configuration) end end activeldap-5.2.4/test/test_validation.rb0000644000004100000410000002317413464071751020402 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'al-test-utils' class TestValidation < Test::Unit::TestCase include AlTestUtils include ActiveLdap::Helper class TestAttributeMethod < self priority :must priority :normal def test_symbol assert_true(@user_class.attribute_method?(:cn)) end def test_string assert_true(@user_class.attribute_method?("cn")) end def test_upper_case assert_true(@user_class.attribute_method?(:CN)) end def test_mixed_case assert_true(@user_class.attribute_method?(:Cn)) end def test_snake_case assert_true(@user_class.attribute_method?(:common_name)) end def test_full_name assert_true(@user_class.attribute_method?(:commonName)) end end priority :must priority :normal def test_octet_string make_temporary_user(:simple => true) do |user,| utf8_encoded_binary_value = "\xff".force_encoding("UTF-8") user.user_password = utf8_encoded_binary_value assert_true(user.save) assert_equal([], user.errors.full_messages) end end def test_rename_duplicated make_temporary_user(:simple => true) do |user1,| make_temporary_user(:simple => true) do |user2,| user1.id = user2.id assert_false(user1.save) format = la_('distinguishedName').humanize format << ' ' << _("is duplicated: %s") assert_equal([format % [user2.dn.to_s]], user1.errors.full_messages) end end end def test_not_show_binary_value make_temporary_user do |user,| user.user_certificate = nil user.jpeg_photo = "XXX" assert_not_predicate(user, :save) format = la_('jpegPhoto').humanize format << ' ' << _("has invalid format: %s: required syntax: %s: %s") arguments = [_(""), lsd_("1.3.6.1.4.1.1466.115.121.1.28"), _("invalid JPEG format")] message = format % arguments assert_equal([message], user.errors.full_messages) end end def test_validation_skip_attributes make_temporary_group do |group| group.gid_number = nil assert_raise(ActiveLdap::EntryInvalid) do group.save! end group.validation_skip_attributes << "gidNumber" assert_raise(ActiveLdap::RequiredAttributeMissed) do group.save! end end end def test_set_attributes_with_invalid_dn_attribute_value user = nil assert_nothing_raised do user = @user_class.new(:uid => "=", :cn => "#") end assert(!user.valid?) end def test_set_attribute_to_invalid_dn_attribute_value_object user = @user_class.new("=") assert_nothing_raised do user.uid_number = 11111 end assert_equal(11111, user.uid_number) end def test_dn_validate_on_new user = @user_class.new("=") assert(!user.valid?) reason = _("attribute value is missing") invalid_format = _("%s is invalid distinguished name (DN): %s") invalid_message = invalid_format % ["uid==,#{user.class.base}", reason] format = la_('distinguishedName').humanize format << ' ' << _("is invalid: %s") message = format % invalid_message assert_equal([message], user.errors.full_messages.find_all {|m| /DN/ =~ m}) end def test_dn_validate make_temporary_user do |user,| user.uid = "=" assert(!user.valid?) reason = _("attribute value is missing") invalid_format = _("%s is invalid distinguished name (DN): %s") invalid_message = invalid_format % ["uid==,#{user.class.base}", reason] format = la_('distinguishedName').humanize format << ' ' << _("is invalid: %s") message = format % invalid_message assert_equal([message], user.errors.full_messages) end end def test_not_validate_empty_string make_temporary_user do |user,| assert(user.valid?) user.uid_number = "" assert(!user.valid?) format = la_('uidNumber').humanize format << ' ' << _("is required attribute by objectClass '%s'") blank_message = format % loc_("posixAccount") assert_equal([blank_message], user.errors.full_messages) end end def test_validate_excluded_classes make_temporary_user do |user,| assert(user.save) user.class.excluded_classes = ['person'] assert(!user.save) format = la_("objectClass").humanize format << ' ' << n_("has excluded value: %s", "has excluded values: %s", 1) message = format % loc_("person") assert_equal([message], user.errors.full_messages) end end def test_valid_subtype_and_single_value make_temporary_user do |user, password| user.display_name = [{"lang-ja" => ["ユーザ"]}, {"lang-en" => "User"}] assert(user.save) user = user.class.find(user.dn) assert_equal([{"lang-ja" => "ユーザ"}, {"lang-en" => "User"}].sort_by {|hash| hash.keys.first}, user.display_name.sort_by {|hash| hash.keys.first}) end end def test_invalid_subtype_and_single_value assert_invalid_display_name_value(["User1", "User2"], ["User1", "User2"]) assert_invalid_display_name_value(["User3", "User4"], [{"lang-en" => ["User3", "User4"]}], {"lang-en" => ["User3", "User4"]}.inspect) assert_invalid_display_name_value(["U2", "U3"], [{"lang-ja" => ["User1"]}, {"lang-en" => ["U2", "U3"]}], [{"lang-ja" => "User1"}, {"lang-en" => ["U2", "U3"]}].inspect) end def test_validate_required_ldap_values make_temporary_user(:simple => true) do |user, password| assert(user.save) user.add_class("strongAuthenticationUser") user.user_certificate = nil assert(!user.save) assert(user.errors[:userCertificate].any?) assert_equal(1, user.errors.size) end end def test_syntax_validation make_temporary_user do |user, password| assert(user.save) user.see_also = "cn=test,dc=example,dc=com" assert(user.save) end assert_invalid_see_also_value("test", "test") assert_invalid_see_also_value("test-en", ["cn=test,dc=example,dc=com", {"lang-en-us" => "test-en"}], "lang-en-us") assert_invalid_see_also_value("test-ja-jp", ["cn=test,dc=example,dc=com", {"lang-ja-jp" => ["cn=test-ja,dc=example,dc=com", "test-ja-jp"]}], "lang-ja-jp") end def test_duplicated_dn_creation assert(ou_class.new("YYY").save) ou = ou_class.new("YYY") assert(!ou.save) format = la_("distinguishedName").humanize format << ' ' << _("is duplicated: %s") message = format % ou.dn assert_equal([message], ou.errors.full_messages) end def test_save! make_temporary_group do |group| group.description = "" assert_nothing_raised do group.save! end @group_class.validates_presence_of(:description) assert_raises(ActiveLdap::EntryInvalid) do group.save! end end end def test_validates_presence_of make_temporary_group do |group| assert_nothing_raised do group.description = "" end assert(group.valid?) assert_equal([], group.errors.to_a) @group_class.validates_presence_of(:description) assert(!group.valid?) assert(group.errors[:description].any?) assert_equal(1, group.errors.size) end end private def assert_invalid_value(name, formatted_value, syntax, reason, model, option) syntax_description = lsd_(syntax) assert_not_nil(syntax_description) params = [formatted_value, syntax_description, reason] params.unshift(option) if option localized_name = la_(name).humanize format = localized_name << ' ' if option format << _("(%s) has invalid format: %s: required syntax: %s: %s") else format << _("has invalid format: %s: required syntax: %s: %s") end message = format % params assert_equal([message], model.errors.full_messages) end def assert_invalid_see_also_value(invalid_value, value, option=nil) make_temporary_user do |user, password| assert(user.save) user.see_also = "cn=test,dc=example,dc=com" assert(user.save) user.see_also = value assert(!user.save) assert(user.errors[:seeAlso].any?) assert_equal(1, user.errors.size) reason_params = [invalid_value, _("attribute value is missing")] reason = _('%s is invalid distinguished name (DN): %s') % reason_params assert_invalid_value("seeAlso", value.inspect, "1.3.6.1.4.1.1466.115.121.1.12", reason, user, option) end end def assert_invalid_display_name_value(invalid_value, value, formatted_value=nil) make_temporary_user do |user, password| assert(user.save) user.display_name = value assert(!user.save) reason_params = [la_("displayName"), invalid_value.inspect] reason = _('Attribute %s can only have a single value: %s') % reason_params assert_invalid_value("displayName", formatted_value || value.inspect, "1.3.6.1.4.1.1466.115.121.1.15", reason, user, nil) end end end activeldap-5.2.4/test/test_object_class.rb0000644000004100000410000000511313464071751020674 0ustar www-datawww-datarequire 'al-test-utils' class TestObjectClass < Test::Unit::TestCase include AlTestUtils priority :must def test_pass_nil_to_set_classes make_temporary_group do |group| assert_raises(ActiveLdap::RequiredObjectClassMissed) do group.classes = nil end end end priority :normal def test_pass_nil_to_replace_class make_temporary_group do |group| assert_raises(ActiveLdap::RequiredObjectClassMissed) do group.replace_class(nil) end end end def test_case_insensitive_match assert_nothing_raised do @group_class.send(:instantiate, [ "cn=test-group,#{@group_class.base}", { :cn => "test-group", :objectClass => ["TOP", "posixgroup"], } ]) end end def test_ensure_recommended_classes make_temporary_group do |group| added_class = "labeledURIObject" assert_equal([], group.class.recommended_classes) group.class.recommended_classes += [added_class] assert_equal([added_class], group.class.recommended_classes) assert_equal([added_class], group.class.recommended_classes - group.classes) group.ensure_recommended_classes assert_equal([], group.class.recommended_classes - group.classes) end end def test_unknown_object_class make_temporary_group do |group| assert_raises(ActiveLdap::ObjectClassError) do group.add_class("unknownObjectClass") end end end def test_remove_required_class make_temporary_group do |group| assert_raises(ActiveLdap::RequiredObjectClassMissed) do group.remove_class("posixGroup") end end end def test_invalid_object_class_value make_temporary_group do |group| assert_raises(TypeError) {group.add_class(:posixAccount)} end end class TestRemoveClass < self def test_clear_existing_attributes make_temporary_user(:simple => true) do |user, password| user.add_class("inetOrgPerson") user.given_name = "new given name" original_attributes = user.attributes user.remove_class("inetOrgPerson") new_attributes = user.attributes original_attributes.delete("objectClass") removed_attributes = original_attributes.reject do |key, value| value == new_attributes[key] end assert_equal({"givenName" => "new given name"}, removed_attributes) end end end end activeldap-5.2.4/test/run-test.rb0000755000004100000410000000164113464071751016770 0ustar www-datawww-data#!/usr/bin/env ruby $VERBOSE = true $KCODE = 'u' if RUBY_VERSION < "1.9" base_dir = File.expand_path(File.dirname(__FILE__)) top_dir = File.expand_path(File.join(base_dir, "..")) lib_dir = File.join(top_dir, "lib") test_dir = File.join(top_dir, "test") $LOAD_PATH.unshift(lib_dir) $LOAD_PATH.unshift(test_dir) require "rubygems" require "bundler/setup" require "test/unit" require "test/unit/notify" Test::Unit::Priority.enable Dir.glob(File.join(test_dir, "**", "test_*.rb")) do |test_file| require test_file end succeeded = true target_adapters = [ENV["ACTIVE_LDAP_TEST_ADAPTER"]] # target_adapters << "ldap" # target_adapters << "net-ldap" # target_adapters << "jndi" target_adapters.each do |adapter| ENV["ACTIVE_LDAP_TEST_ADAPTER"] = adapter puts "using adapter: #{adapter ? adapter : 'default'}" unless Test::Unit::AutoRunner.run(false, nil, ARGV.dup) succeeded = false end puts end exit(succeeded) activeldap-5.2.4/test/test_reflection.rb0000644000004100000410000001403213464071751020373 0ustar www-datawww-datarequire 'al-test-utils' class TestReflection < Test::Unit::TestCase include AlTestUtils priority :must priority :normal def test_base_class assert_equal(ActiveLdap::Base, ActiveLdap::Base.base_class) assert_equal(@user_class, @user_class.base_class) sub_user_class = Class.new(@user_class) assert_equal(@user_class, sub_user_class.base_class) end def test_respond_to? make_temporary_user do |user, password| attributes = (user.must + user.may).collect(&:name) - ["objectClass"] _wrap_assertion do attributes.each do |name| assert_respond_to(user, name) end assert_not_respond_to(user, "objectClass") end user.replace_class(user.class.required_classes) new_attributes = collect_attributes(user.class.required_classes) new_attributes -= ["objectClass"] _wrap_assertion do assert_not_equal([], new_attributes) new_attributes.each do |name| assert_respond_to(user, name) end remained_attributes = (attributes - new_attributes) assert_not_equal([], remained_attributes) remained_attributes.each do |name| assert_not_respond_to(user, name) end end end end def test_methods make_temporary_user do |user, password| assert_equal(user.methods.uniq.size, user.methods.size) assert_equal(user.methods(false).uniq.size, user.methods(false).size) end make_temporary_user do |user, password| attributes = user.must.collect(&:name) + user.may.collect(&:name) attributes = (attributes - ["objectClass"]).map(&:to_sym) assert_equal([], attributes - user.methods) assert_methods_with_only_required_classes(user, attributes) end make_temporary_user do |user, password| user.remove_class("inetOrgPerson") attributes = user.must.collect(&:name) + user.may.collect(&:name) attributes = (attributes - ["objectClass"]).map(&:to_sym) assert_equal([], attributes - user.methods) assert_methods_with_only_required_classes(user, attributes) end make_temporary_user do |user, password| attributes = user.must.collect(&:name) + user.may.collect(&:name) attributes = attributes.map(&:downcase).map(&:to_sym) assert_not_equal([], attributes - user.methods) assert_not_equal([], attributes - user.methods(false)) normalize_attributes_list = Proc.new do |*attributes_list| attributes_list.collect do |attrs| attrs.collect {|x| x.downcase} end end assert_methods_with_only_required_classes(user, attributes, &normalize_attributes_list) end make_temporary_user do |user, password| attributes = user.must.collect(&:name) + user.may.collect(&:name) attributes -= ["objectClass"] attributes = attributes.collect(&:underscore).map(&:to_sym) assert_equal([], attributes - user.methods) normalize_attributes_list = Proc.new do |*attributes_list| attributes_list.collect do |attrs| attrs.collect(&:underscore) end end assert_methods_with_only_required_classes(user, attributes, &normalize_attributes_list) end make_temporary_user do |user, password| user.remove_class("inetOrgPerson") attributes = user.must.collect(&:name) + user.may.collect(&:name) attributes -= ["objectClass"] attributes = attributes.collect(&:underscore).map(&:to_sym) assert_equal([], attributes - user.methods) normalize_attributes_list = Proc.new do |*attributes_list| attributes_list.collect do |attrs| attrs.collect(&:underscore) end end assert_methods_with_only_required_classes(user, attributes, &normalize_attributes_list) end end def test_attribute_names make_temporary_user do |user, password| attributes = collect_attributes(user.classes) assert_equal([], attributes.uniq - user.attribute_names) assert_equal([], user.attribute_names - attributes.uniq) end end private def assert_methods_with_only_required_classes(object, attributes) old_classes = (object.classes - object.class.required_classes).uniq old_attributes = collect_attributes(old_classes, false).uniq.sort required_attributes = collect_attributes(object.class.required_classes, false).uniq.sort if block_given? old_attributes, required_attributes = yield(old_attributes, required_attributes) end [old_attributes, required_attributes].map{|a| a.map!(&:to_sym)} object.replace_class(object.class.required_classes) assert_equal([], old_attributes - (attributes - object.methods - required_attributes) - required_attributes) end def assert_respond_to(object, name) assert_true(object.respond_to?(name), name) assert_true(object.respond_to?("#{name}="), "#{name}=") assert_true(object.respond_to?("#{name}?"), "#{name}?") assert_true(object.respond_to?("#{name}_before_type_cast"), "#{name}_before_type_cast") end def assert_not_respond_to(object, name) assert_false(object.respond_to?(name), name) assert_false(object.respond_to?("#{name}="), "#{name}=") assert_false(object.respond_to?("#{name}?"), "#{name}?") assert_false(object.respond_to?("#{name}_before_type_cast"), "#{name}_before_type_cast") end def collect_attributes(object_classes, with_aliases=true) attributes = [] object_classes.each do |object_class| object_klass = ActiveLdap::Base.schema.object_class(object_class) if with_aliases (object_klass.must + object_klass.may).each do |attribute| attributes << attribute.name attributes.concat(attribute.aliases) end else attributes.concat((object_klass.must + object_klass.may).collect(&:name)) end end attributes end end activeldap-5.2.4/test/al-test-utils.rb0000644000004100000410000002701013464071751017711 0ustar www-datawww-datarequire 'test-unit' require 'erb' require 'yaml' require 'socket' require 'rbconfig' require 'tempfile' require 'active_ldap' require File.join(File.expand_path(File.dirname(__FILE__)), "command") LDAP_ENV = "test" unless defined?(LDAP_ENV) module AlTestUtils def self.included(base) base.class_eval do include ActiveLdap::GetTextSupport include Utilities include Config include Connection include Populate include TemporaryEntry include CommandSupport include MockLogger end end module Utilities def dn(string) ActiveLdap::DN.parse(string) end end module Config def setup super @base_dir = File.expand_path(File.dirname(__FILE__)) @top_dir = File.expand_path(File.join(@base_dir, "..")) @example_dir = File.join(@top_dir, "examples") @fixtures_dir = File.join(@base_dir, "fixtures") @config_file = File.join(@base_dir, "config.yaml") ActiveLdap::Base.configurations = read_config end def teardown super end def current_configuration ActiveLdap::Base.configurations[LDAP_ENV] end def read_config unless File.exist?(@config_file) raise "config file for testing doesn't exist: #{@config_file}" end erb = ERB.new(File.read(@config_file)) erb.filename = @config_file config = YAML.load(erb.result) _adapter = adapter config.each do |key, value| value["adapter"] = _adapter if _adapter end config end def adapter ENV["ACTIVE_LDAP_TEST_ADAPTER"] end def fixture(*components) File.join(@fixtures_dir, *components) end end module ExampleFile def certificate_path File.join(@example_dir, 'example.der') end @@certificate = nil def certificate return @@certificate if @@certificate if File.exist?(certificate_path) @@certificate = read_binary_file(certificate_path) return @@certificate end require 'openssl' rsa = OpenSSL::PKey::RSA.new(512) comment = "Generated by Ruby/OpenSSL" cert = OpenSSL::X509::Certificate.new cert.version = 3 cert.serial = 0 subject = [["OU", "test"], ["CN", Socket.gethostname]] name = OpenSSL::X509::Name.new(subject) cert.subject = name cert.issuer = name cert.not_before = Time.now cert.not_after = Time.now + (365*24*60*60) cert.public_key = rsa.public_key ef = OpenSSL::X509::ExtensionFactory.new(nil, cert) ef.issuer_certificate = cert cert.extensions = [ ef.create_extension("basicConstraints","CA:FALSE"), ef.create_extension("keyUsage", "keyEncipherment"), ef.create_extension("subjectKeyIdentifier", "hash"), ef.create_extension("extendedKeyUsage", "serverAuth"), ef.create_extension("nsComment", comment), ] aki = ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") cert.add_extension(aki) cert.sign(rsa, OpenSSL::Digest::SHA1.new) @@certificate = cert.to_der @@certificate end def jpeg_photo_path File.join(@example_dir, 'example.jpg') end def jpeg_photo read_binary_file(jpeg_photo_path) end def read_binary_file(path) File.open(path, "rb") do |input| input.set_encoding("ascii-8bit") if input.respond_to?(:set_encoding) input.read end end end module Connection def setup super ActiveLdap::Base.setup_connection end def teardown ActiveLdap::Base.remove_active_connections! super end end module Populate def setup @dumped_data = nil super begin @dumped_data = ActiveLdap::Base.dump(:scope => :sub) rescue ActiveLdap::ConnectionError end ActiveLdap::Base.delete_all(nil, :scope => :sub) populate end def teardown if @dumped_data ActiveLdap::Base.setup_connection ActiveLdap::Base.delete_all(nil, :scope => :sub) ActiveLdap::Base.load(@dumped_data) end super end def populate populate_base populate_ou populate_user_class populate_group_class populate_associations end def populate_base ActiveLdap::Populate.ensure_base end def ou_class(prefix="") ou_class = Class.new(ActiveLdap::Base) ou_class.ldap_mapping(:dn_attribute => "ou", :prefix => prefix, :classes => ["top", "organizationalUnit"]) ou_class end def dc_class(prefix="") dc_class = Class.new(ActiveLdap::Base) dc_class.ldap_mapping(:dn_attribute => "dc", :prefix => prefix, :classes => ["top", "dcObject", "organization"]) dc_class end def entry_class(prefix="") entry_class = Class.new(ActiveLdap::Base) entry_class.ldap_mapping(:prefix => prefix, :scope => :sub, :classes => ["top"]) entry_class.dn_attribute = nil entry_class end def populate_ou %w(Users Groups).each do |name| make_ou(name) end end def make_ou(name) ActiveLdap::Populate.ensure_ou(name) end def make_dc(name) ActiveLdap::Populate.ensure_dc(name) end def populate_user_class @user_class = Class.new(ActiveLdap::Base) @user_class_classes = ["posixAccount", "person"] @user_class.ldap_mapping :dn_attribute => "uid", :prefix => "ou=Users", :scope => :sub, :classes => @user_class_classes assign_class_name(@user_class, "User") end def populate_group_class @group_class = Class.new(ActiveLdap::Base) @group_class.ldap_mapping :prefix => "ou=Groups", :scope => :sub, :classes => ["posixGroup"] assign_class_name(@group_class, "Group") end def populate_associations @user_class.belongs_to :groups, :many => "memberUid" @user_class.belongs_to :primary_group, :foreign_key => "gidNumber", :primary_key => "gidNumber" @group_class.has_many :members, :wrap => "memberUid" @group_class.has_many :primary_members, :foreign_key => "gidNumber", :primary_key => "gidNumber" @user_class.set_associated_class(:groups, @group_class) @user_class.set_associated_class(:primary_group, @group_class) @group_class.set_associated_class(:members, @user_class) @group_class.set_associated_class(:primary_members, @user_class) end def assign_class_name(klass, name) singleton_class = class << klass; self; end singleton_class.send(:define_method, :name) do name end if Object.const_defined?(klass.name) Object.send(:remove_const, klass.name) end Object.const_set(klass.name, klass) end end module TemporaryEntry include ExampleFile def setup super @user_index = 0 @group_index = 0 end def make_temporary_user(config={}) @user_index += 1 uid = config[:uid] || "temp-user#{@user_index}" ensure_delete_user(uid) do password = config[:password] || "password#{@user_index}" uid_number = config[:uid_number] || default_uid gid_number = config[:gid_number] || default_gid home_directory = config[:home_directory] || "/nonexistent" see_also = config[:see_also] _wrap_assertion do assert(!@user_class.exists?(uid)) assert_raise(ActiveLdap::EntryNotFound) do @user_class.find(uid).dn end user = @user_class.new(uid) assert(user.new_entry?) user.cn = user.uid user.sn = user.uid user.uid_number = uid_number user.gid_number = gid_number user.home_directory = home_directory user.user_password = ActiveLdap::UserPassword.ssha(password) user.see_also = see_also unless config[:simple] user.add_class('shadowAccount', 'inetOrgPerson', 'organizationalPerson') user.user_certificate = certificate user.jpeg_photo = jpeg_photo end user.save assert(!user.new_entry?) yield(@user_class.find(user.uid), password) end end end def make_temporary_group(config={}) @group_index += 1 cn = config[:cn] || "temp-group#{@group_index}" ensure_delete_group(cn) do gid_number = config[:gid_number] || default_gid _wrap_assertion do assert(!@group_class.exists?(cn)) assert_raise(ActiveLdap::EntryNotFound) do @group_class.find(cn) end group = @group_class.new(cn) assert(group.new_entry?) group.gid_number = gid_number assert(group.save) assert(!group.new_entry?) yield(@group_class.find(group.cn)) end end end def ensure_delete_user(uid) yield(uid) ensure if @user_class.exists?(uid) @user_class.search(:value => uid) do |dn, attribute| @user_class.remove_connection(dn) @user_class.delete(dn) end end end def ensure_delete_group(cn) yield(cn) ensure @group_class.delete(cn) if @group_class.exists?(cn) end def default_uid "10000#{@user_index}" end def default_gid "10000#{@group_index}" end end module CommandSupport def setup super @fakeroot = "fakeroot" @ruby = File.join(::RbConfig::CONFIG["bindir"], ::RbConfig::CONFIG["RUBY_INSTALL_NAME"]) @top_dir = File.expand_path(File.join(File.dirname(__FILE__), "..")) @examples_dir = File.join(@top_dir, "examples") @lib_dir = File.join(@top_dir, "lib") @ruby_args = [ "-I", @examples_dir, "-I", @lib_dir, ] end def run_command(*args, &block) file = Tempfile.new("al-command-support") file.open file.puts(ActiveLdap::Base.configurations["test"].to_yaml) file.close run_ruby(*[@command, "--config", file.path, *args], &block) end def run_ruby(*ruby_args, &block) args = [@ruby, *@ruby_args] args.concat(ruby_args) Command.run(*args, &block) end def run_ruby_with_fakeroot(*ruby_args, &block) args = [@fakeroot, @ruby, *@ruby_args] args.concat(ruby_args) Command.run(*args, &block) end end module MockLogger def make_mock_logger logger = Object.new class << logger def messages(type) @messages ||= {} @messages[type] ||= [] @messages[type] end def info(content=nil) messages(:info) << (block_given? ? yield : content) end def warn(content=nil) messages(:warn) << (block_given? ? yield : content) end def error(content=nil) messages(:error) << (block_given? ? yield : content) end end logger end def with_mock_logger original_logger = ActiveLdap::Base.logger mock_logger = make_mock_logger ActiveLdap::Base.logger = mock_logger yield(mock_logger) ensure ActiveLdap::Base.logger = original_logger end end end activeldap-5.2.4/benchmark/0000755000004100000410000000000013464071751015630 5ustar www-datawww-dataactiveldap-5.2.4/benchmark/bench-instantiate.rb0000644000004100000410000000435713464071751021566 0ustar www-datawww-database = File.dirname(__FILE__) $LOAD_PATH.unshift(File.expand_path(base)) $LOAD_PATH.unshift(File.expand_path(File.join(base, "..", "lib"))) require "active_ldap" require "benchmark" include ActiveLdap::GetTextSupport argv = ARGV.dup unless argv.include?("--config") argv.unshift("--config", File.join(base, "config.yaml")) end argv, opts, options = ActiveLdap::Command.parse_options(argv) do |opts, options| options.prefix = "ou=People" opts.on("--prefix=PREFIX", _("Specify prefix for benchmarking"), _("(default: %s)") % options.prefix) do |prefix| options.prefix = prefix end end ActiveLdap::Base.setup_connection config = ActiveLdap::Base.configuration LDAP_PREFIX = options.prefix LDAP_USER = config[:bind_dn] LDAP_PASSWORD = config[:password] N_USERS = 100 class ALUser < ActiveLdap::Base ldap_mapping :dn_attribute => 'uid', :prefix => LDAP_PREFIX, :classes => ['posixAccount', 'person'] end def populate_base ActiveLdap::Populate.ensure_base if ActiveLdap::Base.search.empty? raise "Can't populate #{ActiveLdap::Base.base}" end end def populate_users ou_class = Class.new(ActiveLdap::Base) ou_class.ldap_mapping :dn_attribute => "ou", :prefix => "", :classes => ["top", "organizationalUnit"] ou_class.new(LDAP_PREFIX.split(/=/)[1]).save! N_USERS.times do |i| name = i.to_s user = ALUser.new(name) user.uid_number = 100000 + i user.gid_number = 100000 + i user.cn = name user.sn = name user.home_directory = "/nonexistent" user.save! end end def populate populate_base populate_users end def main(do_populate) if do_populate puts(_("Populating...")) dumped_data = ActiveLdap::Base.dump(:scope => :sub) ActiveLdap::Base.delete_all(nil, :scope => :sub) populate puts end Benchmark.bmbm(20) do |x| n = 100 GC.start x.report("search 100 entries") do n.times {ALUser.search} end GC.start x.report("instantiate 1 entry") do n.times {ALUser.first} end end ensure if do_populate puts puts(_("Cleaning...")) ActiveLdap::Base.delete_all(nil, :scope => :sub) ActiveLdap::Base.load(dumped_data) end end main(LDAP_USER && LDAP_PASSWORD) activeldap-5.2.4/benchmark/README.md0000644000004100000410000000461113464071751017111 0ustar www-datawww-data# README This document describes how to run benchmarks under benchmark/ directory. ## Configure your LDAP server You need a LDAP server to run benchmarks. This is dependes on your environment. In this document, we assume that you configure your LDAP server by the following configuration: * host: 127.0.0.1 * base DN: dc=bench,dc=local * encryption: startTLS * bind DN: cn=admin,dc=local * password: secret ## Configure ActiveLdap to connect to your LDAP server You need an ActiveLdap configuration in benchmark/config.yaml to connect to your LDAP server. There is a sample configuration in benchmark/config.yaml.sample. It's good to start from it. % cp benchmark/config.yaml.sample benchmark/config.yaml % editor benchmark/config.yaml The configuration uses the same format of ldap.yaml. ## Run benchmarks You just run a bencmark script. It loads benchmark/config.yaml and populate benchmark data automatically. % ruby benchmark/bench-backend.rb Populating... Rehearsal --------------------------------------------------------------- 1x: AL(LDAP) 0.220000 0.000000 0.220000 ( 0.234775) 1x: AL(Net::LDAP) 0.280000 0.000000 0.280000 ( 0.273048) 1x: AL(LDAP: No Obj) 0.000000 0.000000 0.000000 ( 0.009217) 1x: AL(Net::LDAP: No Obj) 0.060000 0.000000 0.060000 ( 0.056727) 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003261) 1x: Net::LDAP 0.040000 0.000000 0.040000 ( 0.029862) ------------------------------------------------------ total: 0.600000sec user system total real 1x: AL(LDAP) 0.200000 0.000000 0.200000 ( 0.195660) 1x: AL(Net::LDAP) 0.220000 0.000000 0.220000 ( 0.213444) 1x: AL(LDAP: No Obj) 0.010000 0.000000 0.010000 ( 0.009000) 1x: AL(Net::LDAP: No Obj) 0.030000 0.000000 0.030000 ( 0.026847) 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003377) 1x: Net::LDAP 0.020000 0.000000 0.020000 ( 0.022662) Entries processed by Ruby/ActiveLdap + LDAP: 100 Entries processed by Ruby/ActiveLdap + Net::LDAP: 100 Entries processed by Ruby/ActiveLdap + LDAP: (without object creation): 100 Entries processed by Ruby/ActiveLdap + Net::LDAP: (without object creation): 100 Entries processed by Ruby/LDAP: 100 Entries processed by Net::LDAP: 100 Cleaning... activeldap-5.2.4/benchmark/config.yaml.sample0000644000004100000410000000014113464071751021235 0ustar www-datawww-datahost: 127.0.0.1 base: dc=bench,dc=local method: :tls bind_dn: cn=admin,dc=local password: secret activeldap-5.2.4/benchmark/bench-backend.rb0000644000004100000410000001375413464071751020633 0ustar www-datawww-database = File.dirname(__FILE__) $LOAD_PATH.unshift(File.expand_path(base)) $LOAD_PATH.unshift(File.expand_path(File.join(base, "..", "lib"))) require "active_ldap" require "benchmark" include ActiveLdap::GetTextSupport argv = ARGV.dup unless argv.include?("--config") argv.unshift("--config", File.join(base, "config.yaml")) end argv, opts, options = ActiveLdap::Command.parse_options(argv) do |opts, options| options.prefix = "ou=People" opts.on("--prefix=PREFIX", _("Specify prefix for benchmarking"), _("(default: %s)") % options.prefix) do |prefix| options.prefix = prefix end end ActiveLdap::Base.setup_connection config = ActiveLdap::Base.configuration LDAP_HOST = config[:host] LDAP_METHOD = config[:method] if LDAP_METHOD == :ssl LDAP_PORT = config[:port] || URI::LDAPS::DEFAULT_PORT else LDAP_PORT = config[:port] || URI::LDAP::DEFAULT_PORT end LDAP_BASE = config[:base] LDAP_PREFIX = options.prefix LDAP_USER = config[:bind_dn] LDAP_PASSWORD = config[:password] class ALUser < ActiveLdap::Base ldap_mapping :dn_attribute => 'uid', :prefix => LDAP_PREFIX, :classes => ['posixAccount', 'person'] end class ALUserLdap < ALUser end ALUserLdap.setup_connection(config.merge(:adapter => "ldap")) class ALUserNetLdap < ALUser end ALUserNetLdap.setup_connection(config.merge(:adapter => "net-ldap")) def search_al_ldap count = 0 ALUserLdap.find(:all).each do |e| count += 1 end count end def search_al_net_ldap count = 0 ALUserNetLdap.find(:all).each do |e| count += 1 end count end def search_al_ldap_without_object_creation count = 0 ALUserLdap.search.each do |e| count += 1 end count end def search_al_net_ldap_without_object_creation count = 0 ALUserNetLdap.search.each do |e| count += 1 end count end # === search_ldap # def search_ldap(conn) count = 0 conn.search("#{LDAP_PREFIX},#{LDAP_BASE}", LDAP::LDAP_SCOPE_SUBTREE, "(uid=*)") do |e| count += 1 end count end # -- search_ldap def search_net_ldap(conn) count = 0 conn.search(:base => "#{LDAP_PREFIX},#{LDAP_BASE}", :scope => Net::LDAP::SearchScope_WholeSubtree, :filter => "(uid=*)") do |e| count += 1 end count end def ldap_connection require 'ldap' if LDAP_METHOD == :tls conn = LDAP::SSLConn.new(LDAP_HOST, LDAP_PORT, true) else conn = LDAP::Conn.new(LDAP_HOST, LDAP_PORT) end conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3) conn.bind(LDAP_USER, LDAP_PASSWORD) if LDAP_USER and LDAP_PASSWORD conn rescue LoadError nil end def net_ldap_connection require 'net/ldap' net_ldap_conn = Net::LDAP::Connection.new(:host => LDAP_HOST, :port => LDAP_PORT) if LDAP_USER and LDAP_PASSWORD net_ldap_conn.setup_encryption(:method => :start_tls) if LDAP_METHOD == :tls net_ldap_conn.bind(:method => :simple, :username => LDAP_USER, :password => LDAP_PASSWORD) end net_ldap_conn rescue LoadError nil end def populate_base ActiveLdap::Populate.ensure_base if ActiveLdap::Base.search.empty? raise "Can't populate #{ActiveLdap::Base.base}" end end def populate_users ou_class = Class.new(ActiveLdap::Base) ou_class.ldap_mapping :dn_attribute => "ou", :prefix => "", :classes => ["top", "organizationalUnit"] ou_class.new(LDAP_PREFIX.split(/=/)[1]).save! 100.times do |i| name = i.to_s user = ALUser.new(name) user.uid_number = 100000 + i user.gid_number = 100000 + i user.cn = name user.sn = name user.home_directory = "/nonexistent" user.save! end end def populate populate_base populate_users end # === main # def main(do_populate) if do_populate puts(_("Populating...")) dumped_data = ActiveLdap::Base.dump(:scope => :sub) ActiveLdap::Base.delete_all(nil, :scope => :sub) populate puts end # Standard connection # ldap_conn = ldap_connection net_ldap_conn = net_ldap_connection al_ldap_count = 0 al_net_ldap_count = 0 al_ldap_count_without_object_creation = 0 al_net_ldap_count_without_object_creation = 0 ldap_count = 0 net_ldap_count = 0 Benchmark.bmbm(20) do |x| [1].each do |n| GC.start x.report("%3dx: AL(LDAP)" % n) do n.times {al_ldap_count = search_al_ldap} end GC.start x.report("%3dx: AL(Net::LDAP)" % n) do n.times {al_net_ldap_count = search_al_net_ldap} end GC.start x.report("%3dx: AL(LDAP: No Obj)" % n) do n.times do al_ldap_count_without_object_creation = search_al_ldap_without_object_creation end end x.report("%3dx: AL(Net::LDAP: No Obj)" % n) do n.times do al_net_ldap_count_without_object_creation = search_al_net_ldap_without_object_creation end end GC.start if ldap_conn x.report("%3dx: LDAP" % n) do n.times {ldap_count = search_ldap(ldap_conn)} end end GC.start if net_ldap_conn x.report("%3dx: Net::LDAP" % n) do n.times {net_ldap_count = search_net_ldap(net_ldap_conn)} end end end end puts puts(_("Entries processed by Ruby/ActiveLdap + LDAP: %d") % al_ldap_count) puts(_("Entries processed by Ruby/ActiveLdap + Net::LDAP: %d") % \ al_net_ldap_count) puts(_("Entries processed by Ruby/ActiveLdap + LDAP: " \ "(without object creation): %d") % \ al_ldap_count_without_object_creation) puts(_("Entries processed by Ruby/ActiveLdap + Net::LDAP: " \ "(without object creation): %d") % \ al_net_ldap_count_without_object_creation) puts(_("Entries processed by Ruby/LDAP: %d") % ldap_count) puts(_("Entries processed by Net::LDAP: %d") % net_ldap_count) ensure if do_populate puts puts(_("Cleaning...")) ActiveLdap::Base.delete_all(nil, :scope => :sub) ActiveLdap::Base.load(dumped_data) end end main(LDAP_USER && LDAP_PASSWORD) activeldap-5.2.4/LICENSE0000644000004100000410000000506613464071751014712 0ustar www-datawww-dataActiveLdap is copyrighted free software by Will Drewry and Kouhei Sutou . You can redistribute it and/or modify it under either the terms of the GPL (see COPYING file), or the conditions below: 1. You may make and give away verbatim copies of the source form of the software without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may modify your copy of the software in any way, provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or by allowing the author to include your modifications in the software. b) use the modified software only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided. d) make other distribution arrangements with the author. 3. You may distribute the software in object code or executable form, provided that you do at least ONE of the following: a) distribute the executables and library files of the software, together with instructions (in the manual page or equivalent) on where to get the original distribution. b) accompany the distribution with the machine-readable source of the software. c) give non-standard executables non-standard names, with instructions on where to get the original software distribution. d) make other distribution arrangements with the author. 4. You may modify and include the part of the software into any other software (possibly commercial). But some files in the distribution are not written by the author, so that they are not under this terms. They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some files under the ./missing directory. See each file for the copying condition. 5. The scripts and library files supplied as input to or produced as output from the software do not automatically fall under the copyright of the software, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this software. 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. activeldap-5.2.4/examples/0000755000004100000410000000000013464071751015514 5ustar www-datawww-dataactiveldap-5.2.4/examples/lpasswd0000755000004100000410000000217213464071751017121 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME" end if argv.size == 1 name = argv.shift else $stderr.puts opts exit 1 end pwb = Proc.new do |user| user ||= ENV["USER"] ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless User.exists?(name) $stderr.puts("User #{name} doesn't exist.") exit 1 end class PasswordMismatch < RuntimeError end user = User.find(name) count = 0 begin count += 1 pw1 = pwb.call(user.dn) pw2 = pwb.call(user.dn) raise PasswordMismatch if pw1 != pw2 rescue PasswordMismatch puts "Password mismatch!" exit 1 if count == 3 retry end user.user_password = ActiveLdap::UserPassword.ssha(pw1) unless user.save puts "failed" puts user.errors.full_messages exit 1 end activeldap-5.2.4/examples/groupls0000755000004100000410000000203413464071751017134 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " GROUP_NAME" end if argv.size == 1 name = argv.shift else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless Group.exists?(name) $stderr.puts("Group #{name} doesn't exist.") exit 1 end group = Group.find(name) members = [] group.primary_members.each do |mem| members << "#{mem.uid}[#{mem.uidNumber}]" end group.members.each do |mem| if mem.new_entry? members << "#{mem.uid}[????]" else members << "#{mem.uid}[#{mem.uidNumber}]" end end puts("#{group.id}(#{group.gid_number}): #{members.join(', ')}") activeldap-5.2.4/examples/objects/0000755000004100000410000000000013464071751017145 5ustar www-datawww-dataactiveldap-5.2.4/examples/objects/group.rb0000644000004100000410000000114313464071751020625 0ustar www-datawww-dataclass Group < ActiveLdap::Base ldap_mapping :dn_attribute => "cn", :classes => ['posixGroup'] # Inspired by ActiveRecord, this tells ActiveLDAP that the # LDAP entry has a attribute which contains one or more of # some class |:class_name| where the attributes name is # |:local_key|. This means that it will call # :class_name.new(value_of(:local_key)) to create the objects. has_many :members, :class_name => "User", :wrap => "memberUid" has_many :primary_members, :class_name => 'User', :foreign_key => 'gidNumber', :primary_key => 'gidNumber' end # Group activeldap-5.2.4/examples/objects/user.rb0000644000004100000410000000132013464071751020444 0ustar www-datawww-datarequire 'objects/group' class User < ActiveLdap::Base ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=People', :classes => ['person', 'posixAccount'] belongs_to :primary_group, :class_name => "Group", :foreign_key => "gidNumber", :primary_key => "gidNumber" belongs_to :groups, :many => 'memberUid' # An example of using the old "return_objects" API with the # new ActiveRecord-style API. alias groups_mapping groups def groups(return_objects=true) return groups_mapping if return_objects attr = 'cn' Group.search(:attribute => 'memberUid', :value => id, :attributes => [attr]).map {|dn, attrs| attrs[attr]}.flatten end end activeldap-5.2.4/examples/objects/ou.rb0000644000004100000410000000021613464071751020114 0ustar www-datawww-dataclass Ou < ActiveLdap::Base ldap_mapping :dn_attribute => 'ou', :prefix => '', :classes => ['top', 'organizationalUnit'] end activeldap-5.2.4/examples/userdel0000755000004100000410000000133613464071751017110 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME" end if argv.size == 1 name = argv.shift else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless User.exists?(name) $stderr.puts("User #{name} doesn't exist.") exit 1 end User.destroy(name) activeldap-5.2.4/examples/usermod-binary-add-time0000755000004100000410000000230113464071751022060 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME CN UID" end if argv.size == 3 name, cn, uid = argv else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless User.exists?(name) $stderr.puts("User #{name} doesn't exist.") exit 1 end 100.times do |i| user = User.find(name) user.cn = cn user.uid_number = uid user.gid_number = uid user.add_class('strongAuthenticationUser') cert_file = File.join(File.dirname(__FILE__), 'example.der') File.open(cert_file) do |input| input.set_encoding("ascii-8bit") if input.respond_to?(:set_encoding) user.user_certificate = input.read end unless user.save puts "failed #{i}" puts user.errors.full_messages exit 1 end # puts "success [#{i}]" end activeldap-5.2.4/examples/example.der0000644000004100000410000000132213464071751017641 0ustar www-datawww-data0060  *H 0T1 0 UAU10U Same-State1!0U Internet Widgits Pty Ltd1 0 Udemo0 040930031605Z 050930031605Z0T1 0 UAU10U Some-State1!0U Internet Widgits Pty Ltd1 0 Udemo00  *H 0I,z2 Eٲ sNT1\)եi^ 2YDQCvVة8D\帅a.eilZO/ڦ w$r^P j۔00Uehw[fi/?? pwb, :allow_anonymous => false) if Ou.exists?(name) $stderr.puts("Ou #{name} already exists.") exit 1 end ou = Ou.new(name) unless ou.save puts "failed" puts ou.errors.full_messages exit 1 end activeldap-5.2.4/examples/useradd-binary0000755000004100000410000000230313464071751020351 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME CN UID" end if argv.size == 3 name, cn, uid = argv else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) if User.exists?(name) $stderr.puts("User #{name} already exists.") exit 1 end user = User.new(name) user.add_class('shadowAccount') user.cn = cn user.sn = "somesn" user.uid_number = uid user.gid_number = uid user.home_directory = "/home/#{name}" user.add_class('strongAuthenticationUser') cert_file = File.join(File.dirname(__FILE__), 'example.der') File.open(cert_file) do |input| input.set_encoding("ascii-8bit") if input.respond_to?(:set_encoding) user.user_certificate = input.read end unless user.save puts "failed" puts user.errors.full_messages exit 1 end activeldap-5.2.4/examples/config.yaml.example0000644000004100000410000000014613464071751021300 0ustar www-datawww-datahost: 127.0.0.1 method: :tls base: dc=localdomain bind_dn: cn=admin,dc=localdomain #adapter: net-ldap activeldap-5.2.4/examples/groupmod0000755000004100000410000000153313464071751017300 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " GROUP_NAME GID_NUMBER" end if argv.size == 2 name, gid = argv else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless Group.exists?(name) $stderr.puts("Group #{name} doesn't exist.") exit 1 end group = Group.find(name) group.gid_number = gid unless group.save puts "failed" puts group.errors.full_messages exit 1 end activeldap-5.2.4/examples/groupadd0000755000004100000410000000151513464071751017251 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " GROUP_NAME" end if argv.size == 1 name = argv.shift else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) if Group.exists?(name) $stderr.puts("Group #{name} already exists.") exit 1 end group = Group.new(name) group.gid_number = 9000 unless group.save puts "failed" puts group.errors.full_messages exit 1 end activeldap-5.2.4/examples/example.jpg0000644000004100000410000003006613464071751017656 0ustar www-datawww-dataJFIFHHCreated with The GIMP. C  #!!!$'$ & ! C  "D!1AQ"aq2#Bb%R3r$5s+!1"2AQaq3B ?:J;DK ~ytfrߏy.iI ɴ=p;;5 6c$ N6GF1OUA<}N((B($(But+E*RNM7v!}ؓU.2QK 2eSl!GbNr߯>TNJ-ٕw].ON {ꝳ)Z&iO$ [Ycb,|t~+mFWn 'G1 J8* ,yAMN:Cp-i$I¹?*]QEYQE$QRHQE$k=wbQ-Ӯ到Gl5z~.nX#-s95MkF5_hv{Pf ,}2X`Džg\CܦFv2mZVw&i7b%V-R؎spi@^*W՗o"9۹sƪ($(N{5*KN2w)$5iۣg?+cb̨OW3Uu uQEzY +GPYL!}SnR cAO|NXv\Z|6!H='H7i5H\bIy[_^FEc}Fjʫw,jQnYTpv?H5u FAm`5 %eY0$Ll'*ץ- |!09>(;>>ĕ[kK#vX#sg/=Cd>o32U0;r{Sm֘+{`1Yr~5B:J̜6Ko }jo4pa>lFR p2j^k ;K~FuSwŲYTQ^^De(''B($*:|PhZu{' ;dI<@3_ 2OI2uzP5+ =ՖhKFp #=.^]Y"gr8q&NsjI@?U)$׉,.(63qWfg'ݓ6Fԭ.=vBAN,3dm:WZm+[v $019^CꋋJEQ%x 䌩>nk dfX,OsǟFs*tE.Z] s)vƟK ؕdY<G#5vd͑rQOFg1Z42qwy' #sY OUj b\<=1+  $PsJ>3En".tn/|XyV5 y\;|5 [u]TsYT h6cb$Ҽx5i  \q޷,qn9q(U{,"p7ɧؽ ܃j~Msu-vrSnPF3jOCrx0yV%,rϱʔ ;۶[v3]#Ng+ǓX+iY ⓴ڲV+ˈ2YЏOy1xVBּk ;kޙrĹK0gT18"/g,=+gF R["~6]ӟe!8沛@Y%$/,9%kS[6~8ҡsxgyX~5"Ne|ncHk6]QVraY}qVݟPXz,)mm%}ӹY,`e*OYVC̵dE,hnSS=4XW0VI^;UwUꦺz=?H("MI_ƌ .OTRo:R&'1Nzm7!II*%Lj'?m>4 ^}qvk.uHe4I;Ԏ{$de`iZ]zU%yTœK <ڂn['J_݁$t0bߣ@9'N~gŠ(h(B($u3eKvҴr4uge(~Ң>'P!K I hCg$uw$od lUh$@2N SWMe'ҕ"]5;[AS޴[mwMH6Ӡ]I ?ais wE9nEviAOjaS"*\^ oc@0Xw?lM_c>y:FQ*EFZkV#']QekTPq!}p1Rv˺.!ET~D8GZ&[1tOV!7 pZ0i66V%Ϙ'4 60DF @ YSc,|d"rx'Y#E._|8^[V䃃C A22͍J{\8GYCq^m-c<+ZKl"fbvL ,mټ7^Tj"oUdsOVD)ɯZFSN~!tg @iKs$ xRdFHQ:gG/l2p$"$\[˜Ri_WTM0\B;0~uf ]\{6kdˈRQH5Lv6)KuϑQ{xɣʬQVOC{j$ˏ֦NV[ O]:!$֯Z4-NKƽkx=O4jQE7 (*I 4) C/ u[ LƮRir,BțxVMHAȨnOˑVIi6Fq{E a?rȢfiqzSBll㲷< b8"Xy(dP (4(BauGBԅ=$9fY6UFSfQ׈6{ 0w3޳nj~ zѼcǸ[v 1BRRE'֬y3"y. idjtL1=QE'{@껞ҴT`a'fb>8Ze(,aOBjQjtwQc[A'bQEvvQEI!EYCM*Ƥ2}*I2QE$k_NYJMTqdhGnKRY]$(2'PNQJ::5\;wIԺaIV{YT'ʢY$*|x>ք35ܴh]_3*Ѳ{rE5AËQEy!ETQEI!EQK;QܓD']F#!a{Z ?V`[)NOzKVhn\RQ8'=U[qU^ E'l;Ta"Xǡɧeu 1_jޚN~["':wuocg5ܫwvw5Ok:jM&=<{~@vU&D~Y 7F8> nIoa-V{-sS}^$)wUv9ӓRQj,e o,Z,3*vGH?6U;DF}Ї55_L'hhFQahp W[h?Yn:*}oYL9|t毪 CS36| ${FT&,Ў?:O{@#%Ҩ,.|3;WOHcx60jӮmwc @>m =D.,M(sRHpe1OB9nqM- j2Y)=N-<'H c,y;Y^ꫮ4vf}6mP㜑 lYѵNT p''ַj'إp=iasJ_.ƱY k0|GcX&\gVTK*YB*C/$֟hD`oo~~Q`nk:AKi8ik[lѴЉ0 nc`l0|d 0#S&v.@-@f]k"fX1hUqv+9*O>s#Lh`/N{}?=&Fv10!H. ǖ"A) 26WӡA_G,~ DH'8č"d|UK! T4ŁU@%Xn- Tk%4%Kuh[F(~uj+z~2Yp"-<ڐqDFz_X"2>I,׻Y*%)nHIS΋i"7 sڗ\֢}M%,ݥ lU{}?uz-Ѷ*uxCWs<_hz)u [/ ;`Yu,CJ.C+K{KD:QLfv?VSEqO$n2 Xޣ2zVX%{<U֝<:|c;mn{=7Np&6O?J 8k"ΠaNMl-ZOǻ'Dc8SPqP9󨆕+ [5)wC$T,jF3Rz L; 5Vab@M7lD"5#􎭤 ݬ)pJ/EhFAZʆՕG+}.% q"zfBjzƑ,xy؁HK.>\-dӌR8YQ55b#EZGB|~*98;XH4CuBTJ"ApλEyWqK"m_؎+ӺpngO=L bp`}®PFyVYTu~&PW`K_E.y}jn2FF 0k\Neݹ[0Ic[*UP쵻<1;oBk1n]#=։TPVzlU`uUl7ix F ÒM>i:C1Zǖέ-uDj)g4x rfB# ֓do{Kz=M*mccP͒ja$A#0PgHdk{0 (P }!_iz*Xd11ipF*[5֙2>saaBX+'7mX n#=7I㺬嘜=*tkk9eP ~A']{bߵF QUܗp)mc+]fzbe6qM5#m{ 7!-TGK 5#"G=\luT+\P0YAU5hj~"یbSݟWFČldϑzf7#2<[ܷҦte^t߶i-g>qHEX"Ts*p*I*޿˭a5*ݧۈ?{u_Y]B&k8v1]'E.ÌX\CƱOH\dԕnQCUiYq*_L6猃K+ ;:QEQRHQE$Cf^ȓ}Fq0 \n<-^'P{1״b2XPwgB@}k'm8 $G9=T2hT;cf_dDqpAxKL뒪mf޲/ [O5, eBmi礁Nʨt0EY>]>:V{}jmɞ8TVdoWSKgӬ.[tHޥy+ 8HU^I"ʚznx!q8b5RLq\HgYtF9c{p]lvI9)O7Wr{p'8$ۥ3"p 9 S[ͪXm)6OW8,cIYf N@(!yZA<8ӞI\"Gs pJQ}f(湒=CY/T힑%xFO=Χd9E_ⲺBH#ξ?OMi<}*bظu6.QEZZV6`iPJ! 䏕d$(B($b-xbt\.m I.Rr0k1TeQZp;UQIḉeU62Y*I  =Yߓ)& qƹ4.,N={H_(2f?T[*KLB^65!^Ĩ3F侣/E> dέa(aQF*cDً&QEr-ʻtM؀3I?T {~^}a=28;qo]Zg #Z!ݣHGL˪Ү,Hʐ1ȟVy9'H9Sb&p':h[%4(BvR}S6A؋ *vI+w 1`mc;NNĽxXW2Gei&ɦf_UPKa-ɚPK0>©8Vy9mc6uֺbsK{B&kky衎`{c4A?o\$F᠕D 
Cw,/WhWm_QS#{śUzĶm__:c'cڨ7d)xK*蜚nX]+%EE_Š+Gmm-81dsP<&Wh^7)ws4mc dumb}wRkٝc-(rvzi]S#==xk"x1;z3ϕg7/k CKO4K{{V!MRu V+ fi'DIV $K+"F<4~pm)HR  O'J+" )'Ztŭݽm(6Ί}fٖ{\)+Ha9G|+GCV=QMKŠ($(Q\$:H񝮪*} e$*_u pVQޫ_jzvvݢܔg :e .*ڌ-xi-/a8$Kkz"W\jik$Dz'I04L LT]*v"8I,3W/M|ȗZP2"=θp;5*#'K1\%ʦT*_keU : GW^7X ~uAF>8 4snB54TVUb11%`Y.!Q7~kskr^K4N?n\jљB=|sO/s#% epKt4Ȣ9HqVH%5d}jK@~n$zo!5E zDXqx\c"/"PKyɦE;%;xsvelGloHR݃2E#_"eRG[תo.@rݳ#NEo@uYݬ`wԧK+\Ynݠǘk޿[A{nbP'!vrŏ 㱤%?0xjX7r^O{ @e*x 7R_1QWޅcd1Oq#!ռmGV"S̽/KُR6V(GoqS! '0(40(iXԝOvrdA*I+j6Jt]I/O~Tʲ U}uۺ;RwX{W=2[ᛀ8J 6 D7"iWDd&8%WDa/RSoK5S,)J&0{:{B+.K|}*9*;K"((;Muo]59JC'㚲zwle5¼ƕNJ9.hCżLJA+^H!x?ʵ|ۍijth08KnxJ6qKx<ɫuY3:c9k7R2㸭;0iK#˚4J&a >T^*pJFAW_Czi@$?ҩ<=.=WLi0N1+ezgʚ& ##AExb%kwV9j{& ;Fv8QAQ>b0N_P{{y^YO9tgi&ӵiMhOGIqRč;yRӼj]g&GǭUiCOcv@UqN!ryk~2*a ?Yg'Z>|Q:WUTn}դKt2chY'=4$1g`^׬;Je#43}o'yd['{cݙٷ#S"3`yCrG47Se[YzuWYtε5F1$A8w)^0c;wTZVHx,cUA,w=e;(Qt/,dp+Tҵ ci-Ŕ|Oݷ@~C$m1Հ##5]uӴ~iS(G{+d +J3]Eux!r*ΚsSċj̳-j/Y諦$Cj"QEP:3k P|jSE{0vjү0<]Qn-,KdzFRѮ^N_:ԍ.9* 16 {OɺC}=jVLZ5)GjGM?U*=ڳ(Z&W[CɁr1ͪEgӑk>o-cő+h60*w =5#%̂{~EtƸƪ***=.H+ȄgIPiZ=UN 2,q#j]۹cqX'nKgEY<Ŝ ڳxZQvR%""6K wtEV6rB'oqoEm@GqDs w_hFc yii /HZDa GMmLm"[J$VhbF[`2pC>\*jꥐ*Bb* Lns^,z/fK1'cǕ{ V y=ZZ+n{pk#lN[uQ-㰟@GXt.nTdNI[zt^o9 sPaf*b$*hy}lU%AǨ)ٓwT]f#& G |ϕ*tO[[=DB|?\6`q,r|PtƱ Ρm.̣Ĺi Y9cʝtSLWYoP(@L|LCoYJd֧ b+"Dk* {zx#W֭_gf#Tm|>l_ՐPÖ́d 2JB@QT$v"-P)vi#W hK_4,sSacSս5QEYhQE$QRHQE$MAԝ7yt[Õ?s&}O=DՔ(UQ}clB:un]#2!$2|e2`Ré̻ ;y_{kq& ,se[ʰj='tMy-+gc:"*6G}и&@dDTV?,;q 69c&\[&2#Tc ]60_Ug=n U ~ǜP)4L{1_%͇@jSZrH*yḪKVBbO^^ pwb, :allow_anonymous => false) unless Group.exists?(name) $stderr.puts("Group #{name} doesn't exist.") exit 1 end Group.destroy(name) activeldap-5.2.4/examples/usermod0000755000004100000410000000156413464071751017126 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME CN UID" end if argv.size == 3 name, cn, uid = argv else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless User.exists?(name) $stderr.puts("User #{name} doesn't exist.") exit 1 end user = User.find(name) user.cn = cn user.uid_number = uid user.gid_number = uid unless user.save puts "failed" puts user.errors.full_messages exit 1 end activeldap-5.2.4/examples/useradd0000755000004100000410000000202613464071751017071 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME CN UID" end if argv.size == 3 name, cn, uid = argv else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) ActiveLdap::Populate.ensure_base ActiveLdap::Populate.ensure_ou(User.prefix) if User.exists?(name) $stderr.puts("User #{name} already exists.") exit 1 end user = User.new(name) user.add_class('shadowAccount') user.cn = cn user.uid_number = uid user.gid_number = uid user.home_directory = "/home/#{name}" user.sn = "somesn" unless user.save puts "failed" puts user.errors.full_messages exit 1 end activeldap-5.2.4/examples/usermod-binary-del0000755000004100000410000000177513464071751021156 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME CN UID" end if argv.size == 3 name, cn, uid = argv else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless User.exists?(name) $stderr.puts("User #{name} doesn't exist.") exit 1 end user = User.find(name) user.cn = cn user.uid_number = uid user.gid_number = uid if user.classes.include?('strongAuthenticationUser') user.user_certificate = nil user.remove_class('strongAuthenticationUser') end unless user.save puts "failed" puts user.errors.full_messages exit 1 end activeldap-5.2.4/examples/usermod-lang-add0000755000004100000410000000161513464071751020570 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME CN UID" end if argv.size == 3 name, cn, uid = argv else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless User.exists?(name) $stderr.puts("User #{name} doesn't exist.") exit 1 end user = User.find(name) user.cn = [cn, {'lang-en-us' => cn}] user.uid_number = uid user.gid_number = uid unless user.save puts "failed" puts user.errors.full_messages exit 1 end activeldap-5.2.4/examples/usermod-binary-add0000755000004100000410000000215613464071751021134 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME CN UID" end if argv.size == 3 name, cn, uid = argv else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless User.exists?(name) $stderr.puts("User #{name} doesn't exist.") exit 1 end user = User.find(name) user.cn = cn user.uid_number = uid user.gid_number = uid user.add_class('strongAuthenticationUser') cert_file = File.join(File.dirname(__FILE__), 'example.der') File.open(cert_file) do |input| input.set_encoding("ascii-8bit") if input.respond_to?(:set_encoding) user.user_certificate = input.read end unless user.save puts "failed" puts user.errors.full_messages exit 1 end activeldap-5.2.4/examples/userls0000755000004100000410000000214713464071751016763 0ustar www-datawww-data#!/usr/bin/ruby base = File.expand_path(File.join(File.dirname(__FILE__), "..")) $LOAD_PATH << File.join(base, "lib") $LOAD_PATH << File.join(base, "examples") require 'active_ldap' require 'objects/user' require 'objects/group' require 'base64' argv, opts, options = ActiveLdap::Command.parse_options do |opts, options| opts.banner += " USER_NAME" end if argv.size == 1 name = argv.shift else $stderr.puts opts exit 1 end pwb = Proc.new do |user| ActiveLdap::Command.read_password("[#{user}] Password: ") end ActiveLdap::Base.setup_connection(:password_block => pwb, :allow_anonymous => false) unless User.exists?(name) $stderr.puts("User #{name} doesn't exist.") exit 1 end user = User.find(name) puts user.to_ldif groups = [] primary_group = user.primary_group if primary_group.exists? groups << "#{primary_group.cn}[#{primary_group.gid_number}]" end puts "Groups by name only: #{user.groups(false).join(', ')}" user.groups.sort_by do |group| group.id end.collect do |group| groups << "#{group.cn}[#{group.gid_number}]" end puts "Groups: #{groups.join(', ')}" activeldap-5.2.4/TODO0000644000004100000410000000244313464071751014371 0ustar www-datawww-data- [1.1.x] add :readonly option to :has_many. - Work as framework on Rails. - How to support dSCorePropagationData? ignore it? all systemOnly == "TRUE" attribute can be ignored? - Add parsing position to DistinguishedNameInvalid error like @. - Support TLS optioins (e.g. CA certification file and so on) - Provide FormHelper for LDAP entry's attribute to handle multiple values (["foo", "bar", ...]) and option value ({"binary" => "..."}, {"lang-en-us" => "..."}) - Test SASL bind. - Add result pagination via LDAP::Controls - serialize & serialized_attributes - schema mgmt - how does AR handle it? - columns() -- ? http://api.rubyonrails.com/classes/ActiveRecord/Base.html#M000865 - provide full documentation for new API. - handle all exception raised from Ruby/LDAP and wrap as ActiveLdap exception. I think we need to develop an application using ActiveLdap. - Add locking around Timeout.alarm() to ensure a multithreaded ruby app doesn't hit any race conditions - Add AR matching exceptions: * ActiveRecordError -- ActiveLdapError as base * AssociationTypeMismatch * SerializationTypeMismatch * ConnectionNotEstablished * RecordNotFound * LdapActionInvalid - like StatementInvalid * MultiparameterAssignmentErrors * AttributeAssignmentError * RecordNotSaved activeldap-5.2.4/lib/0000755000004100000410000000000013464071751014444 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap.rb0000644000004100000410000000420213464071751017242 0ustar www-datawww-datarequire "rubygems" require "active_model" require "active_support/core_ext" require "active_ldap/version" module ActiveLdap autoload :Command, "active_ldap/command" end require 'active_ldap/get_text' require 'active_ldap/compatible' require 'active_ldap/base' require 'active_ldap/distinguished_name' require 'active_ldap/ldif' require 'active_ldap/xml' require 'active_ldap/persistence' require 'active_ldap/associations' require 'active_ldap/attributes' require 'active_ldap/attribute_methods' require 'active_ldap/attribute_methods/query' require 'active_ldap/attribute_methods/before_type_cast' require 'active_ldap/attribute_methods/read' require 'active_ldap/attribute_methods/write' require 'active_ldap/attribute_methods/dirty' require 'active_ldap/configuration' require 'active_ldap/connection' require 'active_ldap/operations' require 'active_ldap/object_class' require 'active_ldap/human_readable' require 'active_ldap/acts/tree' require 'active_ldap/populate' require 'active_ldap/escape' require 'active_ldap/user_password' require 'active_ldap/helper' require 'active_ldap/validations' require 'active_ldap/callbacks' ActiveLdap::Base.class_eval do include ActiveLdap::Persistence include ActiveLdap::Associations include ActiveModel::ForbiddenAttributesProtection include ActiveLdap::Attributes include ActiveLdap::AttributeMethods include ActiveLdap::AttributeMethods::BeforeTypeCast include ActiveLdap::AttributeMethods::Write include ActiveLdap::AttributeMethods::Dirty include ActiveLdap::AttributeMethods::Query include ActiveLdap::AttributeMethods::Read include ActiveLdap::Configuration include ActiveLdap::Connection include ActiveLdap::Operations include ActiveLdap::ObjectClass include ActiveLdap::Acts::Tree include ActiveLdap::Validations include ActiveLdap::Callbacks include ActiveLdap::HumanReadable end unless defined?(ACTIVE_LDAP_CONNECTION_ADAPTERS) ACTIVE_LDAP_CONNECTION_ADAPTERS = %w(ldap net_ldap jndi) end ACTIVE_LDAP_CONNECTION_ADAPTERS.each do |adapter| require "active_ldap/adapter/#{adapter}" end require "active_ldap/entry" require "active_ldap/railtie" if defined?(Rails) activeldap-5.2.4/lib/active_ldap/0000755000004100000410000000000013464071751016717 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap/entry_attribute.rb0000644000004100000410000000411313464071751022467 0ustar www-datawww-datarequire "active_ldap/attributes" module ActiveLdap class EntryAttribute include Attributes::Normalizable attr_reader :must, :may, :object_classes, :schemata def initialize(schema, object_classes) @schemata = {} @names = {} @normalized_names = {} @aliases = {} @must = [] @may = [] @object_classes = [] register(schema.attribute('objectClass')) if schema object_classes.each do |objc| # get all attributes for the class object_class = schema.object_class(objc) @object_classes << object_class @must.concat(object_class.must) @may.concat(object_class.may) end @must.uniq! @may.uniq! (@must + @may).each do |attr| # Update attr_method with appropriate register(attr) end end def names(normalize=false) names = @names.keys if normalize names.collect do |name| normalize(name) end.uniq else names end end def normalize(name, allow_normalized_name=false) return name if name.nil? return nil if @names.empty? and @aliases.empty? name = name.to_s real_name = @names[name] real_name ||= @aliases[name.underscore] if real_name real_name elsif allow_normalized_name return nil if @normalized_names.empty? @normalized_names[normalize_attribute_name(name)] else nil end end def exist?(name) not normalize(name).nil? end def all_names @names.keys + @aliases.keys end # register # # Make a method entry for _every_ alias of a valid attribute and map it # onto the first attribute passed in. def register(attribute) real_name = attribute.name return if @schemata.has_key?(real_name) @schemata[real_name] = attribute ([real_name] + attribute.aliases).each do |name| @names[name] = real_name @aliases[name.underscore] = real_name @normalized_names[normalize_attribute_name(name)] = real_name end end end end activeldap-5.2.4/lib/active_ldap/log_subscriber.rb0000644000004100000410000000211413464071751022246 0ustar www-datawww-datamodule ActiveLdap class LogSubscriber < ActiveSupport::LogSubscriber def self.runtime=(value) Thread.current["active_ldap_runtime"] = value end def self.runtime Thread.current["active_ldap_runtime"] ||= 0 end def self.reset_runtime rt, self.runtime = runtime, 0 rt end def initialize super @odd = false end def log_info(event) self.class.runtime += event.duration return unless logger.debug? payload = event.payload info = payload[:info] || {} label = payload[:name] label += ": FAILED" if info[:exception] name = 'LDAP: %s (%.1fms)' % [label, event.duration] inspected_info = info.inspect if odd? name = color(name, CYAN, true) inspected_info = color(inspected_info, nil, true) else name = color(name, MAGENTA, true) end debug " #{name} #{inspected_info}" end def odd? @odd = !@odd end def logger ActiveLdap::Base.logger end end end ActiveLdap::LogSubscriber.attach_to :active_ldap activeldap-5.2.4/lib/active_ldap/version.rb0000644000004100000410000000005213464071751020726 0ustar www-datawww-datamodule ActiveLdap VERSION = "5.2.4" end activeldap-5.2.4/lib/active_ldap/schema/0000755000004100000410000000000013464071751020157 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap/schema/syntaxes.rb0000644000004100000410000003134113464071751022364 0ustar www-datawww-datamodule ActiveLdap class Schema module Syntaxes class << self def [](id) syntax = Base::SYNTAXES[id] if syntax syntax.new else nil end end end class Base include GetTextSupport SYNTAXES = {} printable_character_source = "a-zA-Z\\d\"()+,\\-.\\/:? " PRINTABLE_CHARACTER = /[#{printable_character_source}]/ # UNPRINTABLE_CHARACTER = /[^#{printable_character_source}]/ # def binary? false end def type_cast(value) value end def valid?(value) validate(value).nil? end def validate(value) validate_normalized_value(normalize_value(value), value) end def normalize_value(value) value end end class BitString < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.6"] = self def type_cast(value) return nil if value.nil? if /\A'([01]*)'B\z/ =~ value.to_s $1 else value end end def normalize_value(value) if value.is_a?(String) and /\A[01]*\z/ =~ value "'#{value}'B" else value end end private def validate_normalized_value(value, original_value) if /\A'/ !~ value return _("%s doesn't have the first \"'\"") % original_value.inspect end if /'B\z/ !~ value return _("%s doesn't have the last \"'B\"") % original_value.inspect end if /([^01])/ =~ value[1..-3] return _("%s has invalid character '%s'") % [value.inspect, $1] end nil end end class Boolean < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.7"] = self def type_cast(value) case value when "TRUE" true when "FALSE" false else value end end def normalize_value(value) case value when true, "1" "TRUE" when false, "0" "FALSE" else value end end private def validate_normalized_value(value, original_value) if %w(TRUE FALSE).include?(value) nil else _("%s should be TRUE or FALSE") % original_value.inspect end end end class CountryString < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.11"] = self private def validate_normalized_value(value, original_value) if /\A#{PRINTABLE_CHARACTER}{2,2}\z/i =~ value nil else format = _("%s should be just 2 printable characters") format % original_value.inspect end end end class DistinguishedName < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.12"] = self def type_cast(value) return nil if value.nil? DN.parse(value) rescue DistinguishedNameInvalid value end def normalize_value(value) if value.is_a?(DN) value.to_s else value end end private def validate_normalized_value(value, original_value) DN.parse(value) nil rescue DistinguishedNameInvalid $!.message end end class DirectoryString < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.15"] = self private def validate_normalized_value(value, original_value) value.unpack("U*") nil rescue ArgumentError _("%s has invalid UTF-8 character") % original_value.inspect end end class GeneralizedTime < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.24"] = self FORMAT = /\A (\d{4,4})? (\d{2,2})? (\d{2,2})? (\d{2,2})? (\d{2,2})? (\d{2,2})? ([,.]\d+)? ([+-]\d{4,4}|Z)? \z/x def type_cast(value) return value if value.nil? or value.is_a?(Time) match_data = FORMAT.match(value) if match_data required_components = match_data.to_a[1, 5] return value if required_components.any?(&:nil?) year, month, day, hour, minute = required_components.collect(&:to_i) second = match_data[-3].to_i fraction = match_data[-2] fraction = fraction.to_f if fraction time_zone = match_data[-1] arguments = [ value, year, month, day, hour, minute, second, fraction, time_zone, Time.now, ] if Time.method(:make_time).arity == 11 arguments[2, 0] = nil end begin Time.send(:make_time, *arguments) rescue ArgumentError raise if year >= 1700 out_of_range_messages = ["argument out of range", "time out of range"] raise unless out_of_range_messages.include?($!.message) Time.at(0) rescue RangeError raise if year >= 1700 raise if $!.message != "bignum too big to convert into `long'" Time.at(0) end else value end end def normalize_value(value) if value.is_a?(Time) normalized_value = value.strftime("%Y%m%d%H%M%S") if value.gmt? normalized_value + "Z" else # for timezones with non-zero minutes, such as IST which is +0530, # divmod(3600) will give wrong value of 1800 offset = value.gmtoff / 60 # in minutes normalized_value + ("%+03d%02d" % offset.divmod(60)) end else value end end private def validate_normalized_value(value, original_value) match_data = FORMAT.match(value) if match_data date_data = match_data.to_a[1..-1] missing_components = [] required_components = %w(year month day hour minute) required_components.each_with_index do |component, i| missing_components << component unless date_data[i] end if missing_components.empty? nil else params = [original_value.inspect, missing_components.join(", ")] _("%s has missing components: %s") % params end else _("%s is invalid time format") % original_value.inspect end end end class Integer < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.27"] = self def type_cast(value) return value if value.nil? begin Integer(value) rescue ArgumentError value end end def normalize_value(value) if value.is_a?(::Integer) value.to_s else value end end private def validate_normalized_value(value, original_value) Integer(value) nil rescue ArgumentError _("%s is invalid integer format") % original_value.inspect end end class JPEG < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.28"] = self def binary? true end private def validate_normalized_value(value, original_value) if value.unpack("n")[0] == 0xffd8 nil else _("invalid JPEG format") end end end class NameAndOptionalUID < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.34"] = self private def validate_normalized_value(value, original_value) separator_index = value.rindex("#") if separator_index dn = value[0, separator_index] bit_string = value[(separator_index + 1)..-1] bit_string_reason = BitString.new.validate(bit_string) dn_reason = DistinguishedName.new.validate(dn) if bit_string_reason if dn_reason value_reason = DistinguishedName.new.validate(value) return nil unless value_reason dn_reason else bit_string_reason end else dn_reason end else DistinguishedName.new.validate(value) end end end class NumericString < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.36"] = self private def validate_normalized_value(value, original_value) if /\A\d+\z/ =~ value nil else _("%s is invalid numeric format") % original_value.inspect end end end class OID < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.38"] = self private def validate_normalized_value(value, original_value) DN.parse("#{value}=dummy") nil rescue DistinguishedNameInvalid reason = $!.reason if reason _("%s is invalid OID format: %s") % [original_value.inspect, reason] else _("%s is invalid OID format") % original_value.inspect end end end class OtherMailbox < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.39"] = self private def validate_normalized_value(value, original_value) type, mailbox = value.split('$', 2) if type.empty? return _("%s has no mailbox type") % original_value.inspect end if /(#{UNPRINTABLE_CHARACTER})/i =~ type format = _("%s has unprintable character in mailbox type: '%s'") return format % [original_value.inspect, $1] end if mailbox.blank? return _("%s has no mailbox") % original_value.inspect end nil end end class OctetString < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.40"] = self def binary? true end private def validate_normalized_value(value, original_value) nil end end class PostalAddress < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.41"] = self private def validate_normalized_value(value, original_value) if value.blank? return _("empty string") end begin value.unpack("U*") rescue ArgumentError return _("%s has invalid UTF-8 character") % original_value.inspect end nil end end class PrintableString < Base SYNTAXES["1.3.6.1.4.1.1466.115.121.1.44"] = self private def validate_normalized_value(value, original_value) if value.blank? return _("empty string") end if /(#{UNPRINTABLE_CHARACTER})/i =~ value format = _("%s has unprintable character: '%s'") return format % [original_value.inspect, $1] end nil end end class TelephoneNumber < PrintableString SYNTAXES["1.3.6.1.4.1.1466.115.121.1.50"] = self private def validate_normalized_value(value, original_value) return nil if value.blank? super end end class ObjectSecurityDescriptor < OctetString # @see http://tools.ietf.org/html/draft-armijo-ldap-syntax-00 # Object-Security-Descriptor: 1.2.840.113556.1.4.907 # # Encoded as an Octet-String (OID 1.3.6.1.4.1.1466.115.121.1.40) # # @see http://msdn.microsoft.com/en-us/library/cc223229.aspx # String(NT-Sec-Desc) 1.2.840.113556.1.4.907 SYNTAXES["1.2.840.113556.1.4.907"] = self end class UnicodePwd < OctetString # @see http://msdn.microsoft.com/en-us/library/cc220961.aspx # cn: Unicode-Pwd # ldapDisplayName: unicodePwd # attributeId: 1.2.840.113556.1.4.90 # attributeSyntax: 2.5.5.10 # omSyntax: 4 # isSingleValued: TRUE # schemaIdGuid: bf9679e1-0de6-11d0-a285-00aa003049e2 # systemOnly: FALSE # searchFlags: 0 # systemFlags: FLAG_SCHEMA_BASE_OBJECT # schemaFlagsEx: FLAG_ATTR_IS_CRITICAL # # @see http://msdn.microsoft.com/en-us/library/cc223177.aspx # String(Octet) 2.5.5.10 SYNTAXES["1.2.840.113556.1.4.90"] = self end end end end activeldap-5.2.4/lib/active_ldap/helper.rb0000644000004100000410000000563513464071751020534 0ustar www-datawww-datamodule ActiveLdap module Helper def ldap_attribute_name_gettext(attribute) Base.human_attribute_name(attribute) end alias_method(:la_, :ldap_attribute_name_gettext) def ldap_attribute_description_gettext(attribute) Base.human_attribute_description(attribute) end alias_method(:lad_, :ldap_attribute_description_gettext) def ldap_object_class_name_gettext(object_class) Base.human_object_class_name(object_class) end alias_method(:loc_, :ldap_object_class_name_gettext) def ldap_object_class_description_gettext(object_class) Base.human_object_class_description(object_class) end alias_method(:locd_, :ldap_object_class_description_gettext) def ldap_syntax_name_gettext(syntax) Base.human_syntax_name(syntax) end alias_method(:ls_, :ldap_syntax_name_gettext) def ldap_syntax_description_gettext(syntax) Base.human_syntax_description(syntax) end alias_method(:lsd_, :ldap_syntax_description_gettext) def ldap_field(type, object_name, method, options={}) case type when "radio_button", "check_box", "text_area" form_method = type else form_method = "#{type}_field" end object = options[:object] if object.nil? normalized_object_name = object_name.to_s.sub(/\[\](\])?$/, "\\1") object = instance_variable_get("@#{normalized_object_name}") end values = object.nil? ? nil : object[method, true] values = [nil] if values.blank? required_ldap_options = options.delete(:ldap_options) || [] required_ldap_options.each do |required_ldap_option| found = false values.each do |value| next unless value.is_a?(Hash) if Hash.to_a[0].to_s == required_ldap_option.to_s found = true break end end values << {required_ldap_option => ""} unless found end fields = [] collect_values = Proc.new do |value, ldap_options| case value when Hash value.each do |k, v| collect_values.call(v, ldap_options + [k]) end when Array value.each do |v| collect_values.call(v, ldap_options) end else id = "#{object_name}_#{method}" name = "#{object_name}[#{method}][]" ldap_options.collect.each do |ldap_option| id << "_#{ldap_option}" name << "[#{ldap_option}][]" end ldap_value_options = {:id => id, :name => name, :value => value} field = send(form_method, object_name, method, ldap_value_options.merge(options)) if block_given? field = yield(field, {:options => ldap_options, :value => value}) end fields << field unless field.blank? end end collect_values.call(values, []) fields.join("\n") end end end activeldap-5.2.4/lib/active_ldap/connection.rb0000644000004100000410000001741713464071751021415 0ustar www-datawww-datamodule ActiveLdap module Connection def self.included(base) base.extend(ClassMethods) end module ClassMethods @@active_connections = {} @@allow_concurrency = false def thread_safe_active_connections @@active_connections[Thread.current.object_id] ||= {} end def single_threaded_active_connections @@active_connections end if @@allow_concurrency alias_method :active_connections, :thread_safe_active_connections else alias_method :active_connections, :single_threaded_active_connections end def allow_concurrency=(threaded) #:nodoc: logger.debug {"allow_concurrency=#{threaded}"} if logger return if @@allow_concurrency == threaded clear_all_cached_connections! @@allow_concurrency = threaded method_prefix = threaded ? "thread_safe" : "single_threaded" sing = (class << self; self; end) [:active_connections].each do |method| sing.send(:alias_method, method, "#{method_prefix}_#{method}") end end def active_connection_name @active_connection_name ||= determine_active_connection_name end def remove_active_connections! active_connections.keys.each do |key| remove_connection(key) end end def clear_active_connections! connections = active_connections connections.each do |key, connection| connection.disconnect! end connections.clear end def clear_active_connection_name @active_connection_name = nil ObjectSpace.each_object(Class) do |klass| if klass < self and !klass.name.blank? and !klass.frozen? klass.instance_variable_set("@active_connection_name", nil) end end end def connection conn = nil @active_connection_name ||= nil if @active_connection_name conn = active_connections[@active_connection_name] end unless conn conn = retrieve_connection active_connections[@active_connection_name] = conn end conn end def connection=(adapter) if adapter.is_a?(Adapter::Base) active_connections[active_connection_name] = adapter elsif adapter.is_a?(Hash) config = adapter self.connection = instantiate_adapter(config) elsif adapter.nil? raise ConnectionNotSetup else setup_connection(adapter) end end def instantiate_adapter(config) adapter = (config[:adapter] || default_adapter) normalized_adapter = adapter.downcase.gsub(/-/, "_") adapter_method = "#{normalized_adapter}_connection" unless Adapter::Base.respond_to?(adapter_method) raise AdapterNotFound.new(adapter) end if config.has_key?(:ldap_scope) message = _(":ldap_scope connection option is deprecated. " \ "Use :scope instead.") ActiveSupport::Deprecation.warn(message) config[:scope] ||= config.delete(:ldap_scope) end config = remove_connection_related_configuration(config) Adapter::Base.send(adapter_method, config) end def default_adapter @@default_adapter ||= guess_available_adapter end def connected? active_connections[active_connection_name] ? true : false end def retrieve_connection conn = nil name = active_connection_name raise ConnectionNotSetup unless name conn = active_connections[name] if conn.nil? config = configuration(name) raise ConnectionNotSetup unless config self.connection = config conn = active_connections[name] end raise ConnectionNotSetup if conn.nil? conn end def remove_connection(klass_or_key=self) if klass_or_key.is_a?(Module) key = active_connection_key(klass_or_key) else key = klass_or_key end config = configuration(key) conn = active_connections[key] remove_configuration_by_key(key) active_connections.delete_if {|_key, value| value == conn} conn.disconnect! if conn config end def setup_connection(config=nil) config = ensure_configuration(config) remove_connection clear_active_connection_name key = active_connection_key @active_connection_name = key define_configuration(key, merge_configuration(config)) end def establish_connection(config=nil) message = _("ActiveLdap::Connection.establish_connection has been deprecated " \ "since 1.1.0. " \ "Please use ActiveLdap::Connection.setup_connection instead.") ActiveSupport::Deprecation.warn(message) setup_connection(config) end # Return the schema object def schema connection.schema end private def active_connection_key(k=self) k.name.blank? ? k.object_id : k.name end def determine_active_connection_name key = active_connection_key if active_connections[key] or configuration(key) key elsif self == ActiveLdap::Base nil else superclass.active_connection_name end end def clear_all_cached_connections! if @@allow_concurrency @@active_connections.each_value do |connection_hash_for_thread| connection_hash_for_thread.each_value {|conn| conn.disconnect!} connection_hash_for_thread.clear end else @@active_connections.each_value {|conn| conn.disconnect!} end @@active_connections.clear end def guess_available_adapter if Object.respond_to?(:java) "jndi" else "net-ldap" end end end def setup_connection(config=nil) config = self.class.ensure_configuration(config) config = self.class.configuration.merge(config) config = self.class.merge_configuration(config, self) remove_connection self.class.define_configuration(dn, config) end def establish_connection(config=nil) message = _("ActiveLdap::Connection#establish_connection has been deprecated " \ "since 1.1.0. " \ "Please use ActiveLdap::Connection#setup_connection instead.") ActiveSupport::Deprecation.warn(message) setup_connection(config) end def remove_connection self.class.remove_connection(dn) @connection = nil end def connection conn = @connection return conn if conn have_dn = !@dn.nil? if !have_dn and attribute_name_resolvable_without_connection? begin have_dn = !get_attribute_before_type_cast(dn_attribute)[1].nil? rescue DistinguishedNameInvalid end end conn = self.class.active_connections[dn] || retrieve_connection if have_dn conn || self.class.connection end def connected? connection != self.class.connection end def connection=(adapter) if adapter.nil? or adapter.is_a?(Adapter::Base) @connection = adapter elsif adapter.is_a?(Hash) config = adapter @connection = self.class.instantiate_adapter(config) else setup_connection(adapter) end end def retrieve_connection conn = self.class.active_connections[dn] return conn if conn config = self.class.configuration(dn) return nil unless config conn = self.class.instantiate_adapter(config) @connection = self.class.active_connections[dn] = conn conn end def schema connection.schema end end end activeldap-5.2.4/lib/active_ldap/attribute_methods.rb0000644000004100000410000000121313464071751022767 0ustar www-datawww-datamodule ActiveLdap module AttributeMethods extend ActiveSupport::Concern include ActiveModel::AttributeMethods def methods(singleton_methods = true) target_names = entry_attribute.all_names target_names -= ['objectClass', 'objectClass'.underscore] super + target_names.uniq.collect do |attr| self.class.attribute_method_matchers.collect do |matcher| :"#{matcher.prefix}#{attr}#{matcher.suffix}" end end.flatten end private # overiding ActiveModel::AttributeMethods def attribute_method?(method_name) have_attribute?(method_name, ['objectClass']) end end end activeldap-5.2.4/lib/active_ldap/supported_control.rb0000644000004100000410000000042613464071751023033 0ustar www-datawww-datarequire "active_ldap/ldap_controls" module ActiveLdap class SupportedControl def initialize(controls) @controls = controls @paged_results = @controls.include?(LdapControls::PAGED_RESULTS) end def paged_results? @paged_results end end end activeldap-5.2.4/lib/active_ldap/xml.rb0000644000004100000410000000745613464071751020060 0ustar www-datawww-datarequire 'erb' require 'builder' require 'active_ldap/ldif' module ActiveLdap class Xml class Serializer PRINTABLE_STRING = /[\x20-\x7e\t\r\n]*/n def initialize(dn, attributes, schema, options={}) @dn = dn @attributes = attributes @schema = schema @options = options end def to_s root = @options[:root] indent = @options[:indent] || 2 xml = @options[:builder] || Builder::XmlMarkup.new(:indent => indent) xml.tag!(root) do target_attributes.each do |key, values| values = normalize_values(values).sort_by {|value, _| value} if @schema.attribute(key).single_value? next if values.empty? serialize_attribute_value(xml, key, *values[0]) else serialize_attribute_values(xml, key, values) end end end end private def target_attributes except_dn = false only = @options[:only] || [] except = @options[:except] || [] if !only.empty? attributes = [] except_dn = true only.each do |name| if name == "dn" except_dn = false elsif @attributes.has_key?(name) attributes << [name, @attributes[name]] end end elsif !except.empty? attributes = @attributes.dup except.each do |name| if name == "dn" except_dn = true else attributes.delete(name) end end else attributes = @attributes.dup end attributes = attributes.sort_by {|key, values| key} attributes.unshift(["dn", [@dn]]) unless except_dn attributes end def normalize_values(values) targets = [] values.each do |value| targets.concat(normalize_value(value)) end targets end def normalize_value(value, options=[]) targets = [] case value when Hash value.each do |real_option, real_value| targets.concat(normalize_value(real_value, options + [real_option])) end when Array value.each do |real_value| targets.concat(normalize_value(real_value, options)) end when DN targets.concat(normalize_value(value.to_s, options)) when nil # ignore else if /\A#{PRINTABLE_STRING}\z/ !~ value value = [value].pack("m").gsub(/\n/u, '') options += ["base64"] end xml_attributes = {} options.each do |name, val| xml_attributes[name] = val || "true" end targets << [value, xml_attributes] end targets end def serialize_attribute_values(xml, name, values) return if values.blank? if name == "dn" or @options[:type].to_s.downcase == "ldif" values.each do |value, xml_attributes| serialize_attribute_value(xml, name, value, xml_attributes) end else plural_name = name.pluralize attributes = @options[:skip_types] ? {} : {"type" => "array"} xml.tag!(plural_name, attributes) do values.each do |value, xml_attributes| serialize_attribute_value(xml, name, value, xml_attributes) end end end end def serialize_attribute_value(xml, name, value, xml_attributes) xml.tag!(name, value, xml_attributes) end end def initialize(dn, attributes, schema) @dn = dn @attributes = attributes @schema = schema end def to_s(options={}) Serializer.new(@dn, @attributes, @schema, options).to_s end end XML = Xml end activeldap-5.2.4/lib/active_ldap/railtie.rb0000644000004100000410000000241013464071751020672 0ustar www-datawww-datarequire "locale" require 'active_ldap' require 'rails' Locale.init(:driver => :cgi) module ActiveLdap class Railtie < Rails::Railtie initializer "active_ldap.setup_connection" do ldap_configuration_file = Rails.root.join('config', 'ldap.yml') if File.exist?(ldap_configuration_file) configurations = YAML::load(ERB.new(IO.read(ldap_configuration_file)).result) ActiveLdap::Base.configurations = configurations ActiveLdap::Base.setup_connection else ActiveLdap::Base.class_eval do format =_("You should run 'rails generator active_ldap:scaffold' to make %s.") logger.error(format % ldap_configuration_file) end end end initializer "active_ldap.logger", :before => "active_ldap.setup_connection" do ActiveLdap::Base.logger ||= ::Rails.logger end initializer "active_ldap.action_view_helper" do class ::ActionView::Base include ActiveLdap::Helper end end # Expose Ldap runtime to controller for logging. initializer "active_ldap.log_runtime" do |app| require "active_ldap/railties/controller_runtime" ActiveSupport.on_load(:action_controller) do include ActiveLdap::Railties::ControllerRuntime end end end end activeldap-5.2.4/lib/active_ldap/schema.rb0000644000004100000410000004635713464071751020523 0ustar www-datawww-datamodule ActiveLdap class Schema include GetTextSupport def initialize(entries) @entries = normalize_entries(entries || {}) @schema_info = {} @class_attributes_info = {} @cache = {} end def ids(group) ensure_parse(group) info, ids, aliases = ensure_schema_info(group) _ = info = aliases # for suppress a warning on Ruby 1.9.3 ids.keys end def names(group) alias_map(group).keys end def exist_name?(group, name) alias_map(group).has_key?(normalize_schema_name(name)) end def resolve_name(group, name) alias_map(group)[normalize_schema_name(name)] end # fetch # # This is just like LDAP::Schema#attribute except that it allows # look up in any of the given keys. # e.g. # fetch('attributeTypes', 'cn', 'DESC') # fetch('ldapSyntaxes', '1.3.6.1.4.1.1466.115.121.1.5', 'DESC') def fetch(group, id_or_name, attribute_name) return [] if attribute_name.empty? attribute_name = normalize_attribute_name(attribute_name) value = entry(group, id_or_name)[attribute_name] value ? value.dup : [] end alias_method :[], :fetch NUMERIC_OID_RE = "\\d[\\d\\.]+" DESCRIPTION_RE = "[a-zA-Z][a-zA-Z\\d\\-]*" OID_RE = "(?:#{NUMERIC_OID_RE}|#{DESCRIPTION_RE}-oid)" def entry(group, id_or_name) return {} if group.empty? or id_or_name.empty? unless @entries.has_key?(group) raise ArgumentError, _("Unknown schema group: %s") % group end # Initialize anything that is required info, ids, aliases = ensure_schema_info(group) _ = info # for suppress a warning on Ruby 1.9.3 id, name = determine_id_or_name(id_or_name, aliases) # Check already parsed options first return ids[id] if ids.has_key?(id) schemata = @entries[group] || [] while schema = schemata.shift next unless /\A\s*\(\s*(#{OID_RE})\s*(.*)\s*\)\s*\z/ =~ schema schema_id = $1 rest = $2 if ids.has_key?(schema_id) attributes = ids[schema_id] else attributes = {} ids[schema_id] = attributes end parse_attributes(rest, attributes) (attributes["NAME"] || []).each do |v| normalized_name = normalize_schema_name(v) aliases[normalized_name] = schema_id id = schema_id if id.nil? and name == normalized_name end break if id == schema_id end ids[id || aliases[name]] || {} end def attribute(name) name = name.to_s if name.is_a?(Symbol) cache([:attribute, name]) do Attribute.new(name, self) end end def attributes cache([:attributes]) do names("attributeTypes").collect do |name| attribute(name) end end end def attribute_type(name, attribute_name) cache([:attribute_type, name, attribute_name]) do fetch("attributeTypes", name, attribute_name) end end def object_class(name) cache([:object_class, name]) do ObjectClass.new(name, self) end end def object_classes cache([:object_classes]) do names("objectClasses").collect do |name| object_class(name) end end end def object_class_attribute(name, attribute_name) cache([:object_class_attribute, name, attribute_name]) do fetch("objectClasses", name, attribute_name) end end def dit_content_rule_attribute(name, attribute_name) cache([:dit_content_rule_attribute, name, attribute_name]) do fetch("dITContentRules", name, attribute_name) end end def ldap_syntax(name) cache([:ldap_syntax, name]) do Syntax.new(name, self) end end def ldap_syntaxes cache([:ldap_syntaxes]) do ids("ldapSyntaxes").collect do |id| ldap_syntax(id) end end end def ldap_syntax_attribute(name, attribute_name) cache([:ldap_syntax_attribute, name, attribute_name]) do fetch("ldapSyntaxes", name, attribute_name) end end def dump(output=nil) require 'pp' output ||= STDOUT if output.respond_to?(:write) PP.pp(@entries, output) else open(output, "w") {|out| PP.pp(@entries, out)} end nil end private def cache(key) (@cache[key] ||= [yield])[0] end def ensure_schema_info(group) @schema_info[group] ||= {:ids => {}, :aliases => {}} info = @schema_info[group] [info, info[:ids], info[:aliases]] end def determine_id_or_name(id_or_name, aliases) if /\A[\d\.]+\z/ =~ id_or_name id = id_or_name name = nil else name = normalize_schema_name(id_or_name) id = aliases[name] end [id, name] end # from RFC 2252 attribute_type_description_reserved_names = ["NAME", "DESC", "OBSOLETE", "SUP", "EQUALITY", "ORDERING", "SUBSTR", "SYNTAX", "SINGLE-VALUE", "COLLECTIVE", "NO-USER-MODIFICATION", "USAGE"] syntax_description_reserved_names = ["DESC"] object_class_description_reserved_names = ["NAME", "DESC", "OBSOLETE", "SUP", "ABSTRACT", "STRUCTURAL", "AUXILIARY", "MUST", "MAY"] matching_rule_description_reserved_names = ["NAME", "DESC", "OBSOLETE", "SYNTAX"] matching_rule_use_description_reserved_names = ["NAME", "DESC", "OBSOLETE", "APPLIES"] private_experiment_reserved_names = ["X-[A-Z\\-_]+"] reserved_names = (attribute_type_description_reserved_names + syntax_description_reserved_names + object_class_description_reserved_names + matching_rule_description_reserved_names + matching_rule_use_description_reserved_names + private_experiment_reserved_names).uniq RESERVED_NAMES_RE = /(?:#{reserved_names.join('|')})/ def parse_attributes(str, attributes) str.scan(/([A-Z\-_]+)\s+ (?:\(\s*(\w[\w\-;]*(?:\s+\$\s+\w[\w\-;]*)*)\s*\)| \(\s*([^\)]*)\s*\)| '([^\']*)'| ((?!#{RESERVED_NAMES_RE})[a-zA-Z][a-zA-Z\d\-;]*)| (\d[\d\.\{\}]+)| () )/x ) do |name, multi_amp, multi, string, literal, syntax, no_value| case when multi_amp values = multi_amp.rstrip.split(/\s*\$\s*/) when multi values = multi.scan(/\s*'([^\']*)'\s*/).collect {|value| value[0]} when string values = [string] when literal values = [literal] when syntax values = [syntax] when no_value values = ["TRUE"] end attributes[normalize_attribute_name(name)] ||= [] attributes[normalize_attribute_name(name)].concat(values) end end def alias_map(group) ensure_parse(group) return {} if @schema_info[group].nil? @schema_info[group][:aliases] || {} end def ensure_parse(group) return if @entries[group].nil? unless @entries[group].empty? fetch(group, 'nonexistent', 'nonexistent') end end def normalize_schema_name(name) name.downcase.sub(/;.*$/, '') end def normalize_attribute_name(name) name.upcase.gsub(/_/, "-") end def default_entries { "objectClasses" => [], "attributeTypes" => [], "ldapSyntaxes" => [], "dITContentRules" => [], "matchingRules" => [], } end def normalize_entries(entries) normalized_entries = default_entries normalized_keys = normalized_entries.keys entries.each do |name, values| normalized_name = normalized_keys.find do |key| key.downcase == name end normalized_entries[normalized_name || name] = values end normalized_entries end class Entry include Comparable attr_reader :id, :name, :aliases, :description def initialize(name, schema, group) @schema = schema @name, *@aliases = attribute("NAME", name) @name ||= name @id = @schema.resolve_name(group, @name) collect_info @schema = nil end def eql?(other) self.class == other.class and (id == other.id or (id.nil? and other.nil? and name == other.name)) end def hash id.nil? ? name.hash : id.hash end def <=>(other) name <=> other.name end def to_param name end end class Syntax < Entry attr_reader :length def initialize(id, schema) if /\{(\d+)\}\z/ =~ id id = $PREMATCH @length = Integer($1) else @length = nil end super(id, schema, "ldapSyntaxes") @id = id @name = nil if @name == @id @built_in_syntax = Syntaxes[@id] end def binary? return true if @built_in_syntax and @built_in_syntax.binary? binary_transfer_required? or !human_readable? end def binary_transfer_required? @binary_transfer_required end def human_readable? @human_readable end def valid?(value) validate(value).nil? end def validate(value) if @built_in_syntax @built_in_syntax.validate(value) else nil end end def type_cast(value) if @built_in_syntax @built_in_syntax.type_cast(value) else value end end def normalize_value(value) if @built_in_syntax @built_in_syntax.normalize_value(value) else value end end def <=>(other) id <=> other.id end def to_param id end private def attribute(attribute_name, name=@name) @schema.ldap_syntax_attribute(name, attribute_name) end def collect_info @description = attribute("DESC")[0] @binary_transfer_required = (attribute('X-BINARY-TRANSFER-REQUIRED')[0] == 'TRUE') @human_readable = (attribute('X-NOT-HUMAN-READABLE')[0] != 'TRUE') end end class Attribute < Entry include GetTextSupport include HumanReadable attr_reader :super_attribute def initialize(name, schema) super(name, schema, "attributeTypes") end # read_only? # # Returns true if an attribute is read-only # NO-USER-MODIFICATION def read_only? @read_only end # single_value? # # Returns true if an attribute can only have one # value defined # SINGLE-VALUE def single_value? @single_value end # binary? # # Returns true if the given attribute's syntax is binary syntax, # X-NOT-HUMAN-READABLE or X-BINARY-TRANSFER-REQUIRED def binary? @binary end # Sets binary encoding to value if the given attribute's syntax # is binary syntax. Does nothing otherwise. # @return [void] def apply_encoding(value) return unless binary? case value when Hash value.each_value do |sub_value| apply_encoding(sub_value) end when Array value.each do |sub_value| apply_encoding(sub_value) end else return unless value.respond_to?(:force_encoding) value.force_encoding("ASCII-8BIT") end end # binary_required? # # Returns true if the value MUST be transferred in binary def binary_required? @binary_required end # directory_operation? # # Returns true if an attribute is directory operation. # It means that USAGE contains directoryOperation. def directory_operation? @directory_operation end def syntax @derived_syntax end def valid?(value) validate(value).nil? end def validate(value) error_info = validate_each_value(value) return error_info if error_info begin normalize_value(value) nil rescue AttributeValueInvalid [$!.message] end end def type_cast(value) send_to_syntax(value, :type_cast, value) end def normalize_value(value) normalize_value_internal(value, false) end def syntax_description send_to_syntax(nil, :description) end def human_attribute_name self.class.human_attribute_name(self) end def human_attribute_description self.class.human_attribute_description(self) end def to_hash { :read_only => read_only?, :single_value => single_value?, :binary => binary?, :binary_required => binary_required?, :directory_operation => directory_operation?, :syntax => syntax, :syntax_description => syntax_description, } end private def attribute(attribute_name, name=@name) @schema.attribute_type(name, attribute_name) end def collect_info @description = attribute("DESC")[0] @super_attribute = attribute("SUP")[0] if @super_attribute @super_attribute = @schema.attribute(@super_attribute) @super_attribute = nil if @super_attribute.id.nil? end @read_only = attribute('NO-USER-MODIFICATION')[0] == 'TRUE' @single_value = attribute('SINGLE-VALUE')[0] == 'TRUE' @syntax = attribute("SYNTAX")[0] @syntax = @schema.ldap_syntax(@syntax) if @syntax if @syntax @binary_required = @syntax.binary_transfer_required? @binary = @syntax.binary? @derived_syntax = @syntax else @binary_required = false @binary = false @derived_syntax = nil @derived_syntax = @super_attribute.syntax if @super_attribute end @directory_operation = attribute("USAGE").include?("directoryOperation") end def send_to_syntax(default_value, method_name, *args) _syntax = syntax if _syntax _syntax.send(method_name, *args) else default_value end end def validate_each_value(value, option=nil) failed_reason = nil case value when Hash original_option = option value.each do |sub_option, val| opt = [original_option, sub_option].compact.join(";") failed_reason, option = validate_each_value(val, opt) break if failed_reason end when Array original_option = option value.each do |val| failed_reason, option = validate_each_value(val, original_option) break if failed_reason end else failed_reason = send_to_syntax(nil, :validate, value) end return nil if failed_reason.nil? [failed_reason, option] end def normalize_value_internal(value, have_binary_mark) case value when Array normalize_array_value(value, have_binary_mark) when Hash normalize_hash_value(value, have_binary_mark) else if value.nil? value = [] else value = send_to_syntax(value, :normalize_value, value) end if !have_binary_mark and binary_required? [{'binary' => value}] else value.is_a?(Array) ? value : [value] end end end def normalize_array_value(value, have_binary_mark) if single_value? and value.reject {|v| v.is_a?(Hash)}.size > 1 format = _("Attribute %s can only have a single value: %s") message = format % [human_attribute_name, value.inspect] raise AttributeValueInvalid.new(self, value, message) end if value.empty? if !have_binary_mark and binary_required? [{'binary' => value}] else value end else value.collect do |entry| normalize_value_internal(entry, have_binary_mark)[0] end end end def normalize_hash_value(value, have_binary_mark) if value.size > 1 format = _("Attribute %s: Hash must have one key-value pair only: %s") message = format % [human_attribute_name, value.inspect] raise AttributeValueInvalid.new(self, value, message) end if !have_binary_mark and binary_required? and !have_binary_key?(value) [append_binary_key(value)] else key = value.keys[0] have_binary_mark ||= key == "binary" [{key => normalize_value_internal(value.values[0], have_binary_mark)}] end end def have_binary_key?(hash) key, value = hash.to_a[0] return true if key == "binary" return have_binary_key?(value) if value.is_a?(Hash) false end def append_binary_key(hash) key, value = hash.to_a[0] if value.is_a?(Hash) append_binary_key(value) else hash.merge(key => {"binary" => value}) end end end class ObjectClass < Entry attr_reader :super_classes def initialize(name, schema) super(name, schema, "objectClasses") end def super_class?(object_class) @super_classes.include?(object_class) end def must(include_super_class=true) if include_super_class @all_must else @must end end def may(include_super_class=true) if include_super_class @all_may else @may end end private def collect_info @description = attribute("DESC")[0] @super_classes = collect_super_classes @must, @may, @all_must, @all_may = collect_attributes end def collect_super_classes super_classes = attribute('SUP') loop do start_size = super_classes.size new_super_classes = [] super_classes.each do |super_class| new_super_classes.concat(attribute('SUP', super_class)) end super_classes.concat(new_super_classes) super_classes.uniq! break if super_classes.size == start_size end super_classes.collect do |name| @schema.object_class(name) end end UNWRITABLE_MUST_ATTRIBUTES = ["nTSecurityDescriptor"] def collect_attributes must = attribute('MUST').reject do |name| UNWRITABLE_MUST_ATTRIBUTES.include?(name) end.uniq must = must.collect {|name| @schema.attribute(name)} may = attribute('MAY').uniq.collect {|name| @schema.attribute(name)} all_must = must.dup all_may = may.dup @super_classes.each do |super_class| all_must.concat(super_class.must(false)) all_may.concat(super_class.may(false)) end # Clean out the dupes. all_must.uniq! all_may.uniq! [must, may, all_must, all_may] end def attribute(attribute_name, name=@name) @schema.object_class_attribute(name, attribute_name) + @schema.dit_content_rule_attribute(name, attribute_name) end end end end require 'active_ldap/schema/syntaxes' activeldap-5.2.4/lib/active_ldap/compatible.rb0000644000004100000410000000205613464071751021366 0ustar www-datawww-datamodule ActiveLdap module Compatible module_function if "".respond_to?(:force_encoding) def convert_to_utf8_encoded_object(object) case object when Array object.collect {|element| convert_to_utf8_encoded_object(element)} when Hash encoded = {} object.each do |key, value| key = convert_to_utf8_encoded_object(key) value = convert_to_utf8_encoded_object(value) encoded[key] = value end encoded when String encoded = object.dup encoded.force_encoding("utf-8") encoded = object unless encoded.valid_encoding? encoded else object end end else def convert_to_utf8_encoded_object(object) object end end if "".respond_to?(:lines) def string_to_lines(string) string.lines.to_a end else def string_to_lines(string) ary = [] string.each_line{|l| ary << l} ary end end end end activeldap-5.2.4/lib/active_ldap/escape.rb0000644000004100000410000000032413464071751020503 0ustar www-datawww-datamodule ActiveLdap module Escape module_function def ldap_filter_escape(str) str.to_s.gsub(/\*/, "**") end def ldap_filter_unescape(str) str.to_s.gsub(/\*\*/, "*") end end end activeldap-5.2.4/lib/active_ldap/acts/0000755000004100000410000000000013464071751017651 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap/acts/tree.rb0000644000004100000410000000435213464071751021141 0ustar www-datawww-datamodule ActiveLdap module Acts module Tree def self.included(base) base.class_eval do extend(ClassMethods) association_accessor(:children) do |target| Association::Children.new(target, {}) end end end module ClassMethods def root(options={}) find(:first, options.merge(:scope => :base)) end end # Returns list of ancestors, starting from parent until root. # # subchild1.ancestors # => [child1, root] def ancestors node, nodes = self, [] nodes << node = node.parent while node.parent nodes end # Returns the root node of the tree. def root node = self node = node.parent while node.parent node end # Returns all siblings of the current node. # # subchild1.siblings # => [subchild2] def siblings self_and_siblings - [self] end # Returns all siblings and a reference to the current node. # # subchild1.self_and_siblings # => [subchild1, subchild2] def self_and_siblings parent ? parent.children : [self] end def parent if base == self.class.base nil else find(:first, :base => base, :scope => :base) end end def parent=(entry) if entry.is_a?(String) or entry.is_a?(DN) base = entry.to_s elsif entry.respond_to?(:dn) base = entry.dn.to_s if entry.respond_to?(:clear_association_cache) entry.clear_association_cache end else message = _("parent must be an entry or parent DN: %s") % entry.inspect raise ArgumentError, message end unless new_entry? begin self.class.modify_rdn_entry(dn, "#{dn_attribute}=#{id}", true, base, :connection => connection) rescue NotImplemented self.class.delete_entry(dn, :connection => connection) @new_entry = true end end self.dn = "#{dn_attribute}=#{id},#{base}" save if new_entry? end end end end activeldap-5.2.4/lib/active_ldap/base.rb0000644000004100000410000012144213464071751020162 0ustar www-datawww-data# -*- coding: utf-8 -*- # === activeldap - an OO-interface to LDAP objects inspired by ActiveRecord # Author: Will Drewry # License: See LICENSE and COPYING # Copyright 2004-2006 Will Drewry # Some portions Copyright 2006 Google Inc # # == Summary # ActiveLdap lets you read and update LDAP entries in a completely object # oriented fashion, even handling attributes with multiple names seamlessly. # It was inspired by ActiveRecord so extending it to deal with custom # LDAP schemas is as effortless as knowing the 'ou' of the objects, and the # primary key. (fix this up some) # # == Example # irb> require 'active_ldap' # > true # irb> user = ActiveLdap::User.new("drewry") # > # user.cn # > "foo" # irb> user.common_name # > "foo" # irb> user.cn = "Will Drewry" # > "Will Drewry" # irb> user.cn # > "Will Drewry" # irb> user.save # # require 'English' require 'thread' require 'erb' require 'set' module ActiveLdap # OO-interface to LDAP assuming pam/nss_ldap-style organization with # Active specifics # Each subclass does a ldapsearch for the matching entry. # If no exact match, raise an error. # If match, change all LDAP attributes in accessor attributes on the object. # -- these are ACTUALLY populated from schema - see active_ldap/schema.rb # example # -- extract objectClasses from match and populate # Multiple entries become lists. # If this isn't read-only then lists become multiple entries, etc. class << self include GetTextSupport def const_missing(id) case id when :ConnectionNotEstablished message = _("ActiveLdap::ConnectionNotEstablished has been deprecated " \ "since 1.1.0. " \ "Please use ActiveLdap::ConnectionNotSetup instead.") ActiveSupport::Deprecation.warn(message) const_set("ConnectionNotEstablished", ConnectionNotSetup) ConnectionNotEstablished else super end end end class Error < StandardError include GetTextSupport end # ConfigurationError # # An exception raised when there is a problem with Base.connect arguments class ConfigurationError < Error end # DeleteError # # An exception raised when an ActiveLdap delete action fails class DeleteError < Error end # SaveError # # An exception raised when an ActiveLdap save action failes class SaveError < Error end # AuthenticationError # # An exception raised when user authentication fails class AuthenticationError < Error end # ConnectionError # # An exception raised when the LDAP conenction fails class ConnectionError < Error end # ObjectClassError # # An exception raised when an objectClass is not defined in the schema class ObjectClassError < Error end # AttributeAssignmentError # # An exception raised when there is an issue assigning a value to # an attribute class AttributeAssignmentError < Error end # TimeoutError # # An exception raised when a connection action fails due to a timeout class TimeoutError < Error end class EntryNotFound < Error end class EntryAlreadyExist < Error end class StrongAuthenticationRequired < Error end class DistinguishedNameInputInvalid < Error attr_reader :input def initialize(input=nil) @input = input super(_("invalid distinguished name (DN) to parse: %s") % @input.inspect) end end class DistinguishedNameInvalid < Error attr_reader :dn, :reason def initialize(dn, reason=nil) @dn = dn @reason = reason if @reason message = _("%s is invalid distinguished name (DN): %s") % [@dn, @reason] else message = _("%s is invalid distinguished name (DN)") % @dn end super(message) end end class DistinguishedNameNotSetError < Error end class LdifInvalid < Error attr_reader :ldif, :reason, :line, :column, :nearest def initialize(ldif, reason=nil, line=nil, column=nil) @ldif = ldif @reason = reason @line = line @column = column @nearest = nil if @reason message = _("invalid LDIF: %s:") % @reason else message = _("invalid LDIF:") end if @line and @column @nearest = detect_nearest(@line, @column) snippet = generate_snippet message << "\n#{snippet}\n" end super("#{message}\n#{numbered_ldif}") end NEAREST_MARK = "|@|" private def detect_nearest(line, column) lines = Compatible.string_to_lines(@ldif).to_a nearest = lines[line - 1] || "" if column - 1 == nearest.size # for JRuby 1.0.2 :< nearest << NEAREST_MARK else nearest[column - 1, 0] = NEAREST_MARK end if nearest == NEAREST_MARK nearest = "#{lines[line - 2]}#{nearest}" end nearest end def generate_snippet nearest = @nearest.chomp column_column = ":#{@column}" target_position_info = "#{@line}#{column_column}: " if /\n/ =~ nearest snippet = "%#{Math.log10(@line).truncate}d" % (@line - 1) snippet << " " * column_column.size snippet << ": " snippet << nearest.gsub(/\n/, "\n#{target_position_info}") else snippet = "#{target_position_info}#{nearest}" end snippet end def numbered_ldif return @ldif if @ldif.blank? lines = Compatible.string_to_lines(@ldif) format = "%#{Math.log10(lines.size).truncate + 1}d: %s" i = 0 lines.collect do |line| i += 1 format % [i, line] end.join end end class EntryNotSaved < Error end class RequiredObjectClassMissed < Error end class RequiredAttributeMissed < Error end class EntryInvalid < Error attr_reader :entry def initialize(entry) @entry = entry errors = @entry.errors.full_messages.join(", ") super(errors) end end class OperationNotPermitted < Error end class ConnectionNotSetup < Error end class AdapterNotSpecified < Error end class AdapterNotFound < Error attr_reader :adapter def initialize(adapter) @adapter = adapter super(_("LDAP configuration specifies nonexistent %s adapter") % adapter) end end class UnknownAttribute < Error attr_reader :name def initialize(name) @name = name super(_("%s is unknown attribute") % @name) end end class AttributeValueInvalid < Error attr_reader :attribute, :value def initialize(attribute, value, message) @attribute = attribute @value = value super(message) end end class NotImplemented < Error attr_reader :target def initialize(target) @target = target super(_("not implemented: %s") % @target) end end # Base # # Base is the primary class which contains all of the core # ActiveLdap functionality. It is meant to only ever be subclassed # by extension classes. class Base include GetTextSupport public :gettext public :_ if Object.const_defined?(:Reloadable) if Reloadable.const_defined?(:Deprecated) include Reloadable::Deprecated else include Reloadable::Subclasses end end VALID_LDAP_MAPPING_OPTIONS = [:dn_attribute, :prefix, :scope, :classes, :recommended_classes, :excluded_classes, :sort_by, :order] cattr_accessor :logger cattr_accessor :configurations @@configurations = {} def self.class_local_attr_accessor(search_ancestors, *syms) syms.flatten.each do |sym| class_eval(<<-EOS, __FILE__, __LINE__ + 1) def self.#{sym}(search_superclasses=#{search_ancestors}) @#{sym} ||= nil return @#{sym} if @#{sym} if search_superclasses target = superclass value = nil loop do break nil unless target.respond_to?(:#{sym}) value = target.#{sym} break if value target = target.superclass end value else nil end end def #{sym}; self.class.#{sym}; end def self.#{sym}=(value); @#{sym} = value; end EOS end end class_local_attr_accessor false, :inheritable_prefix, :inheritable_base class_local_attr_accessor true, :dn_attribute, :scope, :sort_by, :order class_local_attr_accessor true, :required_classes, :recommended_classes class_local_attr_accessor true, :excluded_classes class_local_attr_accessor false, :sub_classes class << self # Hide new in Base private :new def inherited(sub_class) super sub_class.module_eval do include GetTextSupport end (self.sub_classes ||= []) << sub_class end # Set LDAP connection configuration up. It doesn't connect # and bind to LDAP server. A connection to LDAP server is # created when it's needed. # # == +config+ # +config+ must be a hash that may contain any of the following fields: # :password_block, :logger, :host, :port, :base, :bind_dn, # :try_sasl, :allow_anonymous # :bind_dn specifies the DN to bind with. # :password_block specifies a Proc object that will yield a String to # be used as the password when called. # :logger specifies a logger object (Logger, Log4r::Logger and s on) # :host sets the LDAP server hostname # :port sets the LDAP server port # :base overwrites Base.base - this affects EVERYTHING # :try_sasl indicates that a SASL bind should be attempted when binding # to the server (default: false) # :sasl_mechanisms is an array of SASL mechanism to try # (default: ["GSSAPI", "CRAM-MD5", "EXTERNAL"]) # :allow_anonymous indicates that a true anonymous bind is allowed when # trying to bind to the server (default: true) # :retries - indicates the number of attempts to reconnect that will be # undertaken when a stale connection occurs. -1 means infinite. # :sasl_quiet - if true, sets @sasl_quiet on the Ruby/LDAP connection # :method - whether to use :ssl, :tls, or :plain (unencrypted) # :retry_wait - seconds to wait before retrying a connection # :scope - dictates how to find objects. ONELEVEL by default to # avoid dn_attr collisions across OUs. Think before changing. # :timeout - time in seconds - defaults to disabled. This CAN interrupt # search() requests. Be warned. # :retry_on_timeout - whether to reconnect when timeouts occur. Defaults # to true # See lib/active_ldap/configuration.rb for defaults for each option def setup_connection(config=nil) super ensure_logger nil end # establish_connection is deprecated since 1.1.0. Please use # setup_connection() instead. def establish_connection(config=nil) message = _("ActiveLdap::Base.establish_connection has been deprecated " \ "since 1.1.0. " \ "Please use ActiveLdap::Base.setup_connection instead.") ActiveSupport::Deprecation.warn(message) setup_connection(config) end def create(attributes=nil, &block) if attributes.is_a?(Array) attributes.collect {|attrs| create(attrs, &block)} else object = new(attributes, &block) object.save object end end # This class function is used to setup all mappings between the subclass # and ldap for use in activeldap # # Example: # ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=People', # :classes => ['top', 'posixAccount'], # :scope => :sub def ldap_mapping(options={}) options = options.symbolize_keys validate_ldap_mapping_options(options) self.dn_attribute = options[:dn_attribute] || default_dn_attribute self.dn_attribute = dn_attribute.to_s if dn_attribute.is_a?(Symbol) self.prefix = options[:prefix] || default_prefix self.scope = options[:scope] self.required_classes = options[:classes] self.recommended_classes = options[:recommended_classes] self.excluded_classes = options[:excluded_classes] self.sort_by = options[:sort_by] self.order = options[:order] public_class_method :new end # Base.base # # This method when included into Base provides # an inheritable, overwritable configuration setting # # This should be a string with the base of the # ldap server such as 'dc=example,dc=com', and # it should be overwritten by including # configuration.rb into this class. # When subclassing, the specified prefix will be concatenated. def base @base ||= compute_base end alias_method :parsed_base, :base # for backward compatibility def base=(value) self.inheritable_base = value @base = nil end def prefix @prefix ||= inheritable_prefix and DN.parse(inheritable_prefix) end def prefix=(value) self.inheritable_prefix = value @prefix = nil @base = nil end alias_method :scope_without_validation=, :scope= def scope=(scope) validate_scope(scope) self.scope_without_validation = scope end def validate_scope(scope) scope = scope.to_sym if scope.is_a?(String) return if scope.nil? or scope.is_a?(Symbol) raise ConfigurationError, _("scope '%s' must be a Symbol") % scope.inspect end def base_class if self == Base or superclass == Base self else superclass.base_class end end def default_search_attribute dn_attribute end def inspect if self == Base super elsif abstract_class? "#{super}(abstract)" else detail = nil begin must = [] may = [] class_names = classes.collect do |object_class| must.concat(object_class.must) may.concat(object_class.may) object_class.name end detail = ["objectClass:<#{class_names.join(', ')}>", "must:<#{inspect_attributes(must)}>", "may:<#{inspect_attributes(may)}>"].join(", ") rescue ActiveLdap::ConnectionNotSetup detail = "not-connected" rescue ActiveLdap::Error detail = "connection-failure" end "#{super}(#{detail})" end end attr_accessor :abstract_class def abstract_class? defined?(@abstract_class) && @abstract_class end def class_of_active_ldap_descendant(klass) if klass.superclass == Base or klass.superclass.abstract_class? klass elsif klass.superclass.nil? raise Error, _("%s doesn't belong in a hierarchy descending " \ "from ActiveLdap") % (name || to_s) else class_of_active_ldap_descendant(klass.superclass) end end def self_and_descendants_from_active_ldap klass = self classes = [klass] while klass != klass.base_class classes << klass = klass.superclass end classes rescue [self] end def human_name(options={}) defaults = self_and_descendants_from_active_ldap.collect do |klass| if klass.name.blank? nil else :"#{klass.name.underscore}" end end defaults << name.humanize defaults = defaults.compact defaults.first || name || to_s end protected def find_real_class(object_classes) (sub_classes || []).each do |sub_class| real_class = sub_class.find_real_class(object_classes) return real_class if real_class end if object_classes.superset?(Set.new(classes)) self else nil end end private def inspect_attributes(attributes) inspected_attribute_names = {} attributes.collect do |attribute| if inspected_attribute_names.has_key?(attribute.name) nil else inspected_attribute_names[attribute.name] = true inspect_attribute(attribute) end end.compact.join(', ') end def inspect_attribute(attribute) syntax = attribute.syntax result = "#{attribute.name}" if syntax and !syntax.description.blank? result << ": #{syntax.description}" end properties = [] properties << "read-only" if attribute.read_only? properties << "binary" if attribute.binary? properties << "binary-required" if attribute.binary_required? result << "(#{properties.join(', ')})" unless properties.empty? result end def validate_ldap_mapping_options(options) options.assert_valid_keys(VALID_LDAP_MAPPING_OPTIONS) end def ensure_logger @@logger ||= configuration[:logger] # Setup default logger to console if @@logger.nil? require 'logger' @@logger = Logger.new(STDERR) @@logger.progname = 'ActiveLdap' @@logger.level = Logger::ERROR end configuration[:logger] ||= @@logger end def instantiate(args) dn, attributes, options = args options ||= {} object_classes_raw = attributes["objectClass"] || attributes["objectclass"] || [] if sub_classes.nil? or object_classes_raw.empty? real_klass = self else object_classes = Set.new object_classes_raw.each do |object_class_raw| object_classes << schema.object_class(object_class_raw) end real_klass = find_real_class(object_classes) || self end obj = real_klass.allocate conn = options[:connection] || connection obj.connection = conn if conn != connection obj.instance_eval do initialize_by_ldap_data(dn, attributes) end obj end def default_dn_attribute dn_attribute = nil parent_class = ancestors[1] if parent_class.respond_to?(:dn_attribute) dn_attribute = parent_class.dn_attribute end dn_attribute || "cn" end def default_prefix if name.blank? nil else "ou=#{name.demodulize.pluralize}" end end def compute_base _base = inheritable_base _base = configuration[:base] if _base.nil? and configuration if _base.nil? target = superclass loop do break unless target.respond_to?(:base) _base = target.base break if _base target = target.superclass end end _prefix = prefix _base ||= connection.naming_contexts.first return _prefix if _base.blank? _base = DN.parse(_base) _base = _prefix + _base if _prefix _base end end self.scope = :sub self.required_classes = ['top'] self.recommended_classes = [] self.excluded_classes = [] ### All instance methods, etc # new # # Creates a new instance of Base initializing all class and all # initialization. Defines local defaults. See examples If multiple values # exist for dn_attribute, the first one put here will be authoritative def initialize(attributes=nil) init_base @new_entry = true initial_classes = required_classes | recommended_classes case attributes when nil self.classes = initial_classes when String, Array, DN self.classes = initial_classes self.dn = attributes when Hash attributes = attributes.clone classes = extract_object_class!(attributes) self.classes = classes | initial_classes self.attributes = attributes else format = _("'%s' must be either nil, DN value as ActiveLdap::DN, " \ "String or Array or attributes as Hash") raise ArgumentError, format % attributes.inspect end yield self if block_given? run_callbacks :initialize unless _initialize_callbacks.empty? end # Returns true if the +comparison_object+ is the same object, or is of # the same type and has the same dn. def ==(comparison_object) comparison_object.equal?(self) or (comparison_object.instance_of?(self.class) and comparison_object.dn == dn and !comparison_object.new_entry?) end # Delegates to == def eql?(comparison_object) self == (comparison_object) end # Delegates to id in order to allow two records of the same type and id # to work with something like: # [ User.find("a"), User.find("b"), User.find("c") ] & # [ User.find("a"), User.find("d") ] # => [ User.find("a") ] def hash return super if @_hashing # workaround for GetText :< _dn = nil begin @_hashing = true _dn = dn rescue DistinguishedNameInvalid, DistinguishedNameNotSetError return super ensure @_hashing = false end _dn.hash end def may entry_attribute.may end def must entry_attribute.must end # attributes # # Return attribute methods so that a program can determine available # attributes dynamically without schema awareness def attribute_names(normalize=false) entry_attribute.names(normalize) end def attribute_present?(name) values = get_attribute(name, true) !values.empty? or values.any? {|x| !(x and x.empty?)} end # exist? # # Return whether the entry exists in LDAP or not def exist? self.class.exists?(dn) end alias_method(:exists?, :exist?) # dn # # Return the authoritative dn def dn @dn ||= compute_dn end def id get_attribute(dn_attribute_with_fallback) end def to_param id end # Returns this entity’s dn wrapped in an Array or nil if the entity' s dn is not set. def to_key [dn] rescue DistinguishedNameNotSetError nil end def dn=(value) set_attribute(dn_attribute_with_fallback, value) end alias_method(:id=, :dn=) alias_method(:dn_attribute_of_class, :dn_attribute) def dn_attribute ensure_update_dn _dn_attribute = @dn_attribute || dn_attribute_of_class to_real_attribute_name(_dn_attribute) || _dn_attribute end def default_search_attribute self.class.default_search_attribute end # Updates a given attribute and saves immediately def update_attribute(name, value) send("#{name}=", value) save end # This performs a bulk update of attributes and immediately # calls #save. def update_attributes(attrs) self.attributes = attrs save end def update_attributes!(attrs) self.attributes = attrs save! end # This returns the key value pairs in @data with all values # cloned def attributes @simplified_data ||= simplify_data(@data) @simplified_data.clone end # This allows a bulk update to the attributes of a record # without forcing an immediate save or validation. # # It is unwise to attempt objectClass updates this way. # Also be sure to only pass in key-value pairs of your choosing. # Do not let URL/form hackers supply the keys. def attributes=(new_attributes) return if new_attributes.blank? assign_attributes(new_attributes) end def assign_attributes(new_attributes) return if new_attributes.blank? _schema = _local_entry_attribute = nil targets = sanitize_for_mass_assignment(new_attributes) targets.each do |key, value| setter = "#{key}=" unless respond_to?(setter) _schema ||= schema attribute = _schema.attribute(key) next if attribute.id.nil? _local_entry_attribute ||= local_entry_attribute _local_entry_attribute.register(attribute) end send(setter, value) end end def to_ldif_record super(dn, normalize_data(@data)) end def to_ldif Ldif.new([to_ldif_record]).to_s end def to_xml(options={}) options = options.dup options[:root] ||= (self.class.name || '').underscore options[:root] = 'anonymous' if options[:root].blank? [:only, :except].each do |attribute_names_key| names = options[attribute_names_key] next if names.nil? options[attribute_names_key] = names.collect do |name| if name.to_s.downcase == "dn" "dn" else to_real_attribute_name(name) end end.compact end XML.new(dn, normalize_data(@data), schema).to_s(options) end def to_s to_ldif end def have_attribute?(name, except=[]) real_name = to_real_attribute_name(name) !real_name.nil? and !except.include?(real_name) end alias_method :has_attribute?, :have_attribute? def [](name, force_array=false) if name == "dn" array_of(dn, force_array) else get_attribute(name, force_array) end end def []=(name, value) set_attribute(name, value) end def bind(config_or_password={}, config_or_ignore=nil, &block) if config_or_password.is_a?(String) config = (config_or_ignore || {}).merge(:password => config_or_password) else config = config_or_password end config = {:bind_dn => dn, :allow_anonymous => false}.merge(config) config[:password_block] ||= block if block_given? setup_connection(config) before_connection = @connection begin @connection = nil connection.connect @connection = connection clear_connection_based_cache clear_association_cache rescue ActiveLdap::Error remove_connection @connection = before_connection raise end true end def clear_connection_based_cache @schema = nil @local_entry_attribute = nil clear_object_class_based_cache end def clear_object_class_based_cache @entry_attribute = nil @real_names = {} clear_changes_information end def clear_removed_attributes_data(removed_attributes) return if removed_attributes.empty? removed_entry_attribute = EntryAttribute.new(nil, []) removed_attributes.each do |attribute| removed_entry_attribute.register(attribute) end @data.reject! do |key, _| removed_entry_attribute.exist?(key) end end def schema @schema ||= super end def base @base ||= compute_base end def base=(object_local_base) ensure_update_dn @dn = nil @base = nil @base_value = object_local_base end alias_method :scope_of_class, :scope def scope @scope || scope_of_class end def scope=(scope) self.class.validate_scope(scope) @scope = scope end def delete_all(options={}) super({:base => dn}.merge(options || {})) end def destroy_all(options={}) super({:base => dn}.merge(options || {})) end def inspect object_classes = entry_attribute.object_classes inspected_object_classes = object_classes.collect do |object_class| object_class.name end.join(', ') must_attributes = must.collect(&:name).sort.join(', ') may_attributes = may.collect(&:name).sort.join(', ') inspected_attributes = attribute_names.sort.collect do |name| inspect_attribute(name) end.join(', ') result = "\#<#{self.class} objectClass:<#{inspected_object_classes}>, " result << "must:<#{must_attributes}>, may:<#{may_attributes}>, " result << "#{inspected_attributes}>" result end private def dn_attribute_with_fallback begin dn_attribute rescue DistinguishedNameInvalid _dn_attribute = @dn_attribute || dn_attribute_of_class _dn_attribute = to_real_attribute_name(_dn_attribute) || _dn_attribute raise if _dn_attribute.nil? _dn_attribute end end def inspect_attribute(name) values = get_attribute(name, true) values.collect do |value| if value.is_a?(String) and value.length > 50 "#{value[0, 50]}...".inspect elsif value.is_a?(Date) || value.is_a?(Time) "#{value.to_s(:db)}" else value.inspect end end "#{name}: #{values.inspect}" end def find_object_class_values(data) data["objectClass"] || data["objectclass"] end def attribute_name_resolvable_without_connection? @entry_attribute and @local_entry_attribute end def entry_attribute @entry_attribute ||= connection.entry_attribute(find_object_class_values(@data) || []) end def local_entry_attribute @local_entry_attribute ||= connection.entry_attribute([]) end def extract_object_class!(attributes) classes = [] attributes.keys.each do |key| string_key = key.to_s if /\Aobject_?class\z/i =~ string_key classes.concat(attributes[key].to_a) attributes.delete(key) end end classes end def remove_dn_attribute!(attributes) _dn_attribute = dn_attribute attributes.keys.each do |key| case key when "id", :id, "dn", :dn attributes.delete(key) else normalized_key = to_real_attribute_name(key) || key if normalized_key == _dn_attribute attributes.delete(key) end end end end def init_base init_instance_variables end def initialize_by_ldap_data(dn, attributes) init_base dn = Compatible.convert_to_utf8_encoded_object(dn) attributes = Compatible.convert_to_utf8_encoded_object(attributes) @original_dn = dn.clone @dn = dn @base = nil @base_value = nil @new_entry = false @dn_is_base = false @ldap_data = attributes attributes = attributes.clone classes = extract_object_class!(attributes) self.classes = classes self.dn = dn remove_dn_attribute!(attributes) initialize_attributes(attributes) yield self if block_given? end def initialize_attributes(attributes) _schema = _local_entry_attribute = nil targets = sanitize_for_mass_assignment(attributes) targets.each do |key, value| unless have_attribute?(key) _schema ||= schema attribute = _schema.attribute(key) _local_entry_attribute ||= local_entry_attribute _local_entry_attribute.register(attribute) end set_attribute(key, value) end clear_changes_information end private :initialize_attributes def instantiate(args) dn, attributes, options = args options ||= {} obj = self.class.allocate obj.connection = options[:connection] || @connection obj.instance_eval do initialize_by_ldap_data(dn, attributes) end obj end def to_real_attribute_name(name, allow_normalized_name=true) return name if name.nil? if allow_normalized_name entry_attribute.normalize(name, allow_normalized_name) || local_entry_attribute.normalize(name, allow_normalized_name) else @real_names[name] ||= entry_attribute.normalize(name, false) || local_entry_attribute.normalize(name, false) end end # enforce_type # # enforce_type applies your changes without attempting to write to LDAP. # This means that if you set userCertificate to somebinary value, it will # wrap it up correctly. def enforce_type(key, value) # Enforce attribute value formatting normalize_attribute(key, value)[1] end def init_instance_variables @mutex = Mutex.new @data = {} # where the r/w entry data is stored @ldap_data = {} # original ldap entry data @dn_attribute = nil @base = nil @scope = nil @dn = nil @dn_is_base = false @dn_split_value = nil @connection ||= nil @_hashing = false clear_connection_based_cache end def register_new_dn_attribute(name, value) @dn = nil @dn_is_base = false if value.blank? @dn_split_value = nil [name, nil] else new_name, new_value, raw_new_value, new_bases = split_dn_value(value) @dn_split_value = [new_name, new_value, new_bases] if new_name.nil? and new_value.nil? new_name, raw_new_value = new_bases[0].to_a[0] end [to_real_attribute_name(new_name) || name, raw_new_value || value] end end def update_dn(new_name, new_value, bases) if new_name.nil? and new_value.nil? @dn_is_base = true @base = nil @base_value = nil attr, value = bases[0].to_a[0] @dn_attribute = attr _ = value # for suppress a warning on Ruby 1.9.3 else new_name ||= @dn_attribute || dn_attribute_of_class new_name = to_real_attribute_name(new_name) if new_name.nil? new_name = @dn_attribute || dn_attribute_of_class new_name = to_real_attribute_name(new_name) end new_bases = bases.empty? ? nil : DN.new(*bases).to_s dn_components = ["#{new_name}=#{new_value}", new_bases, self.class.base.to_s] dn_components = dn_components.find_all {|component| !component.blank?} DN.parse(dn_components.join(',')) @base = nil @base_value = new_bases @dn_attribute = new_name end end def split_dn_value(value) dn_value = relative_dn_value = nil value = value.first if value.is_a?(Array) and value.size == 1 dn_value = value if value.is_a?(DN) begin dn_value ||= DN.parse(value) rescue DistinguishedNameInvalid begin dn_value = DN.parse("#{dn_attribute}=#{value}") rescue DistinguishedNameInvalid return [nil, value, value, []] end end val = bases = nil begin relative_dn_value = dn_value base_of_class = self.class.base relative_dn_value -= base_of_class if base_of_class if relative_dn_value.rdns.empty? val = [] bases = dn_value.rdns else val, *bases = relative_dn_value.rdns end rescue ArgumentError val, *bases = dn_value.rdns end dn_attribute_name, dn_attribute_value = val.to_a[0] escaped_dn_attribute_value = nil unless dn_attribute_value.nil? escaped_dn_attribute_value = DN.escape_value(dn_attribute_value) end [dn_attribute_name, escaped_dn_attribute_value, dn_attribute_value, bases] end def need_update_dn? not @dn_split_value.nil? end def ensure_update_dn return unless need_update_dn? @mutex.synchronize do if @dn_split_value update_dn(*@dn_split_value) @dn_split_value = nil end end end def compute_dn return base if @dn_is_base ensure_update_dn dn_value = id if dn_value.nil? format = _("%s's DN attribute (%s) isn't set") message = format % [self.inspect, dn_attribute] raise DistinguishedNameNotSetError.new, message end dn_value = DN.escape_value(dn_value.to_s) _base = base _base = nil if _base.blank? DN.parse(["#{dn_attribute}=#{dn_value}", _base].compact.join(",")) end def compute_base base_of_class = self.class.base if @base_value.nil? base_of_class else base_of_object = DN.parse(@base_value) base_of_object += base_of_class if base_of_class base_of_object end end # array_of # # Returns the array form of a value, or not an array if # false is passed in. def array_of(value, to_a=true) case value when Array if to_a or value.size > 1 value.collect {|v| array_of(v, false)}.compact else if value.empty? nil else array_of(value.first, to_a) end end when Hash if to_a [value] else result = {} value.each {|k, v| result[k] = array_of(v, to_a)} result end else to_a ? [value] : value end end def normalize_data(data, except=[]) _schema = schema result = {} data.each do |key, values| next if except.include?(key) real_name = to_real_attribute_name(key) next if real_name and except.include?(real_name) real_name ||= key next if _schema.attribute(real_name).id.nil? result[real_name] ||= [] result[real_name].concat(enforce_type(real_name, values)) end result end def simplify_data(data) _schema = schema result = {} data.each do |key, values| attribute = _schema.attribute(key) if attribute.single_value? and values.is_a?(Array) and values.size == 1 values = values[0] end result[key] = type_cast(attribute, values) end result end def collect_modified_attributes(ldap_data, data) klass = self.class _dn_attribute = dn_attribute new_dn_value = nil attributes = [] # Now that all the options will be treated as unique attributes # we can see what's changed and add anything that is brand-spankin' # new. ldap_data.each do |k, v| value = data[k] || [] next if v == value value = klass.remove_blank_value(value) || [] next if v == value if klass.blank_value?(value) and schema.attribute(k).binary_required? value = [{'binary' => []}] end if k == _dn_attribute new_dn_value = value[0] else if (v.size == 1 and value.size == 1) or force_replace?(k) attributes.push([:replace, k, value]) else removed_values = v - value added_values = value - v attributes.push([:delete, k, removed_values]) unless removed_values.empty? attributes.push([:add, k, added_values]) unless added_values.empty? end end end data.each do |k, v| value = v || [] next if ldap_data.has_key?(k) value = klass.remove_blank_value(value) || [] next if klass.blank_value?(value) # Detect subtypes and account for them # REPLACE will function like ADD, but doesn't hit EQUALITY problems # TODO: Added equality(attr) to Schema if force_replace?(k) attributes.push([:replace, k, value]) else attributes.push([:add, k, value]) end end [new_dn_value, attributes] end def force_replace?(k) attribute = schema.attribute(k) attribute.single_value? or attribute.binary? # TODO: this should probably explicitly check for fields with no equality matching rule instead end def collect_all_attributes(data) dn_attr = dn_attribute dn_value = data[dn_attr] attributes = [] attributes.push([dn_attr, dn_value]) oc_value = data['objectClass'] attributes.push(['objectClass', oc_value]) except_keys = ['objectClass', dn_attr].collect(&:downcase) data.each do |key, value| next if except_keys.include?(key.downcase) value = self.class.remove_blank_value(value) next if self.class.blank_value?(value) attributes.push([key, value]) end attributes end def prepare_data_for_saving # Expand subtypes to real ldap_data attributes # We can't reuse @ldap_data because an exception would leave # an object in an unknown state ldap_data = normalize_data(@ldap_data) # Expand subtypes to real data attributes, but leave @data alone object_classes = find_object_class_values(@ldap_data) || [] original_attributes = connection.entry_attribute(object_classes).names bad_attrs = original_attributes - entry_attribute.names data = normalize_data(@data, bad_attrs) success = yield(data, ldap_data) if success @ldap_data = data.clone # Delete items disallowed by objectclasses. # They should have been removed from ldap. bad_attrs.each do |remove_me| @ldap_data.delete(remove_me) end @original_dn = dn.clone end success end end # Base end # ActiveLdap activeldap-5.2.4/lib/active_ldap/entry.rb0000644000004100000410000000027713464071751020413 0ustar www-datawww-datamodule ActiveLdap class Entry < ActiveLdap::Base ldap_mapping :prefix => "", :classes => ["top"], :scope => :sub self.dn_attribute = nil end end activeldap-5.2.4/lib/active_ldap/user_password.rb0000644000004100000410000000616613464071751022155 0ustar www-datawww-datarequire 'English' require 'base64' require 'digest/md5' require 'digest/sha1' module ActiveLdap module UserPassword include GetText module_function def valid?(password, hashed_password) unless /^\{([A-Za-z][A-Za-z\d]+)\}/ =~ hashed_password # Plain text password return hashed_password == password end type = $1 hashed_password_without_type = $POSTMATCH normalized_type = type.downcase unless respond_to?(normalized_type) raise ArgumentError, _("Unknown Hash type: %s") % type end salt_extractor = "extract_salt_for_#{normalized_type}" if respond_to?(salt_extractor) salt = send(salt_extractor, hashed_password_without_type) if salt.nil? raise ArgumentError, _("Can't extract salt from hashed password: %s") % hashed_password end generated_password = send(normalized_type, password, salt) else generated_password = send(normalized_type, password) end hashed_password == generated_password end def crypt(password, salt=nil) salt ||= "$1$#{Salt.generate(8)}" "{CRYPT}#{password.crypt(salt)}" end def extract_salt_for_crypt(crypted_password) if /\A\$(?:1|5|6|2a)\$[a-zA-Z0-9.\/]{,16}\$/ =~ crypted_password $MATCH else salt = crypted_password[0, 2] if salt.size != 2 raise ArgumentError, _("salt size must be 2: <%s>") % salt end unless /\A[a-zA-Z0-9.\/]{2}\z/ =~ salt message = _("salt character must be [a-zA-Z0-9./]: <%s>") % salt raise ArgumentError, message end salt end end def md5(password) "{MD5}#{[Digest::MD5.digest(password)].pack('m').chomp}" end def smd5(password, salt=nil) if salt and salt.size < 4 raise ArgumentError, _("salt size must be >= 4: %s") % salt.inspect end salt ||= Salt.generate(4) md5_hash_with_salt = "#{Digest::MD5.digest(password + salt)}#{salt}" "{SMD5}#{[md5_hash_with_salt].pack('m').gsub("\n", '')}" end def extract_salt_for_smd5(smd5ed_password) extract_salt_at_pos(smd5ed_password, 16) end def sha(password) "{SHA}#{[Digest::SHA1.digest(password)].pack('m').chomp}" end def ssha(password, salt=nil) if salt and salt.size < 4 raise ArgumentError, _("salt size must be >= 4: %s") % salt.inspect end salt ||= Salt.generate(4) sha1_hash_with_salt = "#{Digest::SHA1.digest(password + salt)}#{salt}" "{SSHA}#{[sha1_hash_with_salt].pack('m').gsub("\n", '')}" end def extract_salt_for_ssha(sshaed_password) extract_salt_at_pos(sshaed_password, 20) end def extract_salt_at_pos(hashed_password, position) salt = Base64.decode64(hashed_password)[position..-1] salt == '' ? nil : salt end module Salt CHARS = ['.', '/'] + ['0'..'9', 'A'..'Z', 'a'..'z'].collect do |x| x.to_a end.flatten module_function def generate(length) salt = "" length.times {salt << CHARS[rand(CHARS.length)]} salt end end end end activeldap-5.2.4/lib/active_ldap/distinguished_name.rb0000644000004100000410000001555713464071751023124 0ustar www-datawww-datarequire 'strscan' module ActiveLdap class DistinguishedName include GetTextSupport class Parser include GetTextSupport attr_reader :dn def initialize(source) @dn = nil source = source.to_s if source.is_a?(DN) unless source.is_a?(String) raise DistinguishedNameInputInvalid.new(source) end @source = source end def parse return @dn if @dn rdns = [] scanner = StringScanner.new(@source) scanner.scan(/\s*/) raise rdn_is_missing if scanner.scan(/\s*\+\s*/) raise name_component_is_missing if scanner.scan(/\s*,\s*/) rdn = {} until scanner.eos? type = scan_attribute_type(scanner) skip_attribute_type_and_value_separator(scanner) value = scan_attribute_value(scanner) rdn[type] = value if scanner.scan(/\s*\+\s*/) raise rdn_is_missing if scanner.eos? elsif scanner.scan(/\s*\,\s*/) rdns << rdn rdn = {} raise name_component_is_missing if scanner.eos? else scanner.scan(/\s*/) rdns << rdn if scanner.eos? end end @dn = DN.new(*rdns) @dn end private ATTRIBUTE_TYPE_RE = /\s*([a-zA-Z][a-zA-Z\d\-]*|\d+(?:\.\d+)*)\s*/ def scan_attribute_type(scanner) raise attribute_type_is_missing unless scanner.scan(ATTRIBUTE_TYPE_RE) scanner[1] end def skip_attribute_type_and_value_separator(scanner) raise attribute_value_is_missing unless scanner.scan(/\s*=\s*/) end HEX_PAIR = "(?:[\\da-fA-F]{2})" STRING_CHARS_RE = /[^,=\+<>\#;\\\"]*/ # PAIR_RE = /\\([,=\+<>\#;]|\\|\"| |(#{HEX_PAIR}))/ # HEX_STRING_RE = /\#(#{HEX_PAIR}+)/ # def scan_attribute_value(scanner) if scanner.scan(HEX_STRING_RE) value = scanner[1].scan(/../).collect do |hex_pair| hex_pair.hex end.pack("C*") elsif scanner.scan(/\"/) value = scan_quoted_attribute_value(scanner) else value = scan_not_quoted_attribute_value(scanner) end raise attribute_value_is_missing if value.blank? value end def scan_quoted_attribute_value(scanner) result = "" until scanner.scan(/\"/) scanner.scan(/([^\\\"]*)/) quoted_strings = scanner[1] pairs = collect_pairs(scanner) if scanner.eos? or (quoted_strings.empty? and pairs.empty?) raise found_unmatched_quotation end result << quoted_strings result << pairs end result end def scan_not_quoted_attribute_value(scanner) result = "" until scanner.eos? prev_size = result.size pairs = collect_pairs(scanner) strings = scanner.scan(STRING_CHARS_RE) result << pairs if !pairs.nil? and !pairs.empty? unless strings.nil? if scanner.peek(1) == "," result << strings.rstrip else result << strings end end break if prev_size == result.size end result end def collect_pairs(scanner) result = "" while scanner.scan(PAIR_RE) if scanner[2] result << [scanner[2].hex].pack("C*") else result << scanner[1] end end result.force_encoding("utf-8") if result.respond_to?(:force_encoding) result end def invalid_dn(reason) DistinguishedNameInvalid.new(@source, reason) end def name_component_is_missing invalid_dn(_("name component is missing")) end def rdn_is_missing invalid_dn(_("relative distinguished name (RDN) is missing")) end def attribute_type_is_missing invalid_dn(_("attribute type is missing")) end def attribute_value_is_missing invalid_dn(_("attribute value is missing")) end def found_unmatched_quotation invalid_dn(_("found unmatched quotation")) end end class << self def parse(source) Parser.new(source).parse end def escape_value(value) if /(\A | \z)/.match(value) '"' + value.gsub(/([\\\"])/, '\\\\\1') + '"' else value.gsub(/([,=\+<>#;\\\"])/, '\\\\\1') end end end attr_reader :rdns def initialize(*rdns) @rdns = rdns.collect do |rdn| if rdn.is_a?(Array) and rdn.size == 2 {rdn[0] => rdn[1]} else rdn end end end def blank? @rdns.blank? end def +(other) self.class.new(*(@rdns + other.rdns)) end def -(other) rdns = @rdns.dup normalized_rdns = normalize(@rdns) normalize(other.rdns).reverse_each do |rdn| if rdn == normalized_rdns.pop rdns.pop else raise ArgumentError, _("%s isn't sub DN of %s") % [other, self] end end self.class.new(*rdns) end def <<(rdn) @rdns << rdn self end def unshift(rdn) @rdns.unshift(rdn) end def parent return nil if @rdns.size <= 1 self.class.new(*@rdns[1..-1]) end def <=>(other) other = DN.parse(other) if other.is_a?(String) return nil unless other.is_a?(self.class) normalize_for_comparing(@rdns) <=> normalize_for_comparing(other.rdns) end def ==(other) case other when self.class normalize(@rdns) == normalize(other.rdns) when String parsed_other = nil begin parsed_other = self.class.parse(other) rescue DistinguishedNameInvalid return false end self == parsed_other else false end end def eql?(other) other.is_a?(self.class) and normalize(@rdns).to_s.eql?(normalize(other.rdns).to_s) end def hash normalize(@rdns).to_s.hash end def to_s klass = self.class @rdns.collect do |rdn| rdn.sort_by do |type, value| type.upcase end.collect do |type, value| "#{type}=#{klass.escape_value(value)}" end.join("+") end.join(",") end def to_str # for backward compatibility to_s end def to_human_readable_format to_s.inspect end private def normalize(rdns) rdns.collect do |rdn| normalized_rdn = {} rdn.each do |key, value| normalized_rdn[key.upcase] = value.upcase end normalized_rdn end end def normalize_for_comparing(rdns) normalize(rdns).collect do |rdn| rdn.sort_by do |key, value| key end end.collect do |key, value| [key, value] end end end DN = DistinguishedName end activeldap-5.2.4/lib/active_ldap/configuration.rb0000644000004100000410000001261513464071751022120 0ustar www-datawww-datarequire "English" require "cgi" require 'uri' begin require 'uri/ldaps' rescue LoadError module URI class LDAPS < LDAP DEFAULT_PORT = 636 end @@schemes['LDAPS'] = LDAPS end end module ActiveLdap # Configuration # # Configuration provides the default settings required for # ActiveLdap to work with your LDAP server. All of these # settings can be passed in at initialization time. module Configuration def self.included(base) base.extend(ClassMethods) end DEFAULT_CONFIG = {} DEFAULT_CONFIG[:host] = '127.0.0.1' DEFAULT_CONFIG[:port] = nil DEFAULT_CONFIG[:method] = :plain # :ssl, :tls, :plain allowed DEFAULT_CONFIG[:tls_options] = nil DEFAULT_CONFIG[:bind_dn] = nil DEFAULT_CONFIG[:password_block] = nil DEFAULT_CONFIG[:password] = nil DEFAULT_CONFIG[:store_password] = true DEFAULT_CONFIG[:allow_anonymous] = true DEFAULT_CONFIG[:sasl_quiet] = true DEFAULT_CONFIG[:try_sasl] = false DEFAULT_CONFIG[:sasl_options] = nil # See http://www.iana.org/assignments/sasl-mechanisms DEFAULT_CONFIG[:sasl_mechanisms] = ["GSSAPI", "DIGEST-MD5", "CRAM-MD5", "EXTERNAL"] DEFAULT_CONFIG[:retry_limit] = 1 DEFAULT_CONFIG[:retry_wait] = 1 DEFAULT_CONFIG[:timeout] = 0 # in seconds; 0 <= Never timeout # Whether or not to retry on timeouts DEFAULT_CONFIG[:retry_on_timeout] = true DEFAULT_CONFIG[:follow_referrals] = true DEFAULT_CONFIG[:logger] = nil module ClassMethods @@defined_configurations = {} def default_configuration DEFAULT_CONFIG.dup end def ensure_configuration(config=nil) if config.nil? if defined?(LDAP_ENV) config = LDAP_ENV elsif defined?(Rails) config = Rails.env else config = {} end end if config.is_a?(Symbol) or config.is_a?(String) _config = configurations[config.to_s] unless _config raise ConnectionError, _("%s connection is not configured") % config end config = _config end config end def configuration(key=nil) @@defined_configurations[key || active_connection_name] end def define_configuration(key, config) @@defined_configurations[key] = config end def defined_configurations @@defined_configurations end def remove_configuration_by_key(key) @@defined_configurations.delete(key) end CONNECTION_CONFIGURATION_KEYS = [:uri, :base, :adapter] def remove_connection_related_configuration(config) config.reject do |key, value| CONNECTION_CONFIGURATION_KEYS.include?(key) end end def merge_configuration(user_configuration, target=self) configuration = default_configuration prepare_configuration(user_configuration).each do |key, value| case key when :base # Scrub before inserting target.base = value.gsub(/['}{#]/, '') when :scope, :ldap_scope if key == :ldap_scope message = _(":ldap_scope configuration option is deprecated. " \ "Use :scope instead.") ActiveSupport::Deprecation.warn(message) end target.scope = value configuration[:scope] = value else configuration[key] = value end end configuration end def prepare_configuration(configuration) configuration = configuration.symbolize_keys uri = configuration.delete(:uri) return configuration unless uri begin uri = URI.parse(uri) rescue URI::InvalidURIError raise ConfigurationError.new(_("invalid URI: %s") % uri) end unless uri.is_a?(URI::LDAP) raise ConfigurationError.new(_("not a LDAP URI: %s") % uri.to_s) end merger = URIConfigurationMerger.new(uri) merger.merge(configuration) end class URIConfigurationMerger def initialize(uri) @uri = uri end def merge(configuration) uri_configuration = {:port => @uri.port} uri_configuration[:host] = @uri.host if @uri.host uri_configuration[:base] = @uri.dn if @uri.dn extensions = parse_extensions bindname_extension = extensions["bindname"] if bindname_extension uri_configuration[:bind_dn] = bindname_extension[:value] uri_configuration[:allow_anonymous] = !bindname_extension[:critical] end uri_configuration[:scope] = @uri.scope if @uri.scope uri_configuration[:method] = :ssl if @uri.is_a?(URI::LDAPS) uri_configuration.merge(configuration) end private def parse_extensions extensions = {} (@uri.extensions || "").split(",").collect do |extension| name, value = extension.split("=", 2) case name when /\A!/ critical = true name = $POSTMATCH else critical = false end extensions[name] = { :critical => critical, :value => CGI.unescape(value || ""), } end extensions end end end end end activeldap-5.2.4/lib/active_ldap/attributes.rb0000644000004100000410000000752313464071751021441 0ustar www-datawww-datamodule ActiveLdap module Attributes def self.included(base) base.class_eval do extend(ClassMethods) extend(Normalizable) include(Normalizable) end end module ClassMethods def blank_value?(value) case value when Hash value.values.all? {|val| blank_value?(val)} when Array value.all? {|val| blank_value?(val)} when String /\A\s*\z/ === value when true, false false when nil true else value.blank? end end def remove_blank_value(value) case value when Hash result = {} value.each do |k, v| v = remove_blank_value(v) next if v.nil? result[k] = v end result = nil if result.blank? result when Array result = [] value.each do |v| v = remove_blank_value(v) next if v.nil? result << v end result = nil if result.blank? result when String if /\A\s*\z/ =~ value nil else value end else value end end end module Normalizable def normalize_attribute_name(name) name.to_s.downcase end # Enforce typing: # Hashes are for subtypes # Arrays are for multiple entries def normalize_attribute(name, value) if name.nil? raise RuntimeError, _('The first argument, name, must not be nil. ' \ 'Please report this as a bug!') end name = normalize_attribute_name(name) [name, schema.attribute(name).normalize_value(value)] end def unnormalize_attributes(attributes) result = {} attributes.each do |name, values| unnormalize_attribute(name, values, result) end result end def unnormalize_attribute(name, values, result={}) if values.empty? result[name] = [] else values.each do |value| if value.is_a?(Hash) suffix, real_value = unnormalize_attribute_options(value) new_name = name + suffix unnormalize_attribute(new_name, real_value, result) else result[name] ||= [] if value.is_a?(DN) result[name] << value.to_s else result[name] << value.dup end end end end result end # normalize_attribute_options # # Makes the Hashized value from the full attribute name # e.g. userCertificate;binary => "some_bin" # becomes userCertificate => {"binary" => "some_bin"} def normalize_attribute_options(attr, value) return [attr, value] unless attr.match(/;/) ret_attr, *options = attr.split(/;/) [ret_attr, [options.reverse.inject(value) {|result, option| {option => result}}]] end # unnormalize_attribute_options # # Unnormalizes all of the subtypes from a given set of nested hashes # and returns the attribute suffix and the final true value def unnormalize_attribute_options(value) options = '' ret_val = value if value.class == Hash options = ';' + value.keys[0] ret_val = value[value.keys[0]] if ret_val.class == Hash sub_options, ret_val = unnormalize_attribute_options(ret_val) options += sub_options end end ret_val = [ret_val] unless ret_val.class == Array [options, ret_val] end end private def normalize_attribute_name(name) self.class.normalize_attribute_name(name) end end end activeldap-5.2.4/lib/active_ldap/command.rb0000644000004100000410000000232713464071751020666 0ustar www-datawww-datarequire 'optparse' require 'ostruct' module ActiveLdap module Command include GetTextSupport module_function def parse_options(argv=nil, version=nil) argv ||= ARGV.dup options = OpenStruct.new opts = OptionParser.new do |opts| yield(opts, options) opts.separator "" opts.separator _("Common options:") opts.on_tail("--config=CONFIG", _("Specify configuration file written as YAML")) do |file| require 'yaml' config = YAML.load(File.read(file)).symbolize_keys config = Base.prepare_configuration(config) Configuration::DEFAULT_CONFIG.update(config) end opts.on_tail("-h", "--help", _("Show this message")) do puts opts exit end opts.on_tail("--version", _("Show version")) do puts(version || VERSION) exit end end opts.parse!(argv) [argv, opts, options] end def read_password(prompt, input=$stdin, output=$stdout) output.print(prompt) system("/bin/stty -echo") if input.tty? input.gets.chomp ensure system("/bin/stty echo") if input.tty? output.puts end end end activeldap-5.2.4/lib/active_ldap/railties/0000755000004100000410000000000013464071751020533 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap/railties/controller_runtime.rb0000644000004100000410000000251313464071751025007 0ustar www-datawww-datarequire 'active_support/core_ext/module/attr_internal' require 'active_ldap/log_subscriber' module ActiveLdap module Railties module ControllerRuntime #:nodoc: extend ActiveSupport::Concern private attr_internal :ldap_runtime def process_action(action, *args) # We also need to reset the runtime before each action # because of queries in middleware or in cases we are streaming # and it won't be cleaned up by the method below. ActiveLdap::LogSubscriber.reset_runtime super end def cleanup_view_runtime if ActiveLdap::Base.connected? ldap_rt_before_render = ActiveLdap::LogSubscriber.reset_runtime runtime = super ldap_rt_after_render = ActiveLdap::LogSubscriber.reset_runtime self.ldap_runtime = ldap_rt_before_render + ldap_rt_after_render runtime - ldap_rt_after_render else super end end def append_info_to_payload(payload) super payload[:ldap_runtime] = ldap_runtime end module ClassMethods def log_process_action(payload) messages, ldap_runtime = super, payload[:ldap_runtime] messages << ("ActiveLdap: %.1fms" % ldap_runtime.to_f) if ldap_runtime messages end end end end end activeldap-5.2.4/lib/active_ldap/get_text/0000755000004100000410000000000013464071751020542 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap/get_text/parser.rb0000644000004100000410000001164613464071751022373 0ustar www-datawww-datarequire 'active_ldap' require 'gettext/parser/ruby' module ActiveLdap module GetText class Parser include GetText def initialize(configuration=nil) configuration = ensure_configuration(configuration) configuration = default_configuration.merge(configuration) configuration = extract_options(configuration) ActiveLdap::Base.setup_connection(configuration) end def parse(file, targets=[]) targets = RubyParser.parse(file, targets) if RubyParser.target?(file) extract(targets) do load_constants(file).each do |name| klass = name.constantize next unless klass.is_a?(Class) next unless klass < ActiveLdap::Base register(klass.name.singularize.underscore.gsub(/_/, " "), file) next unless @extract_schema klass.classes.each do |object_class| register_object_class(object_class, file) end end end end def target?(file) @classes_re.match(File.read(file)) end def extract_all_in_schema(targets=[]) extract(targets) do schema = ActiveLdap::Base.schema schema.object_classes.each do |object_class| register_object_class(object_class, "-") end schema.attributes.each do |attribute| register_attribute(attribute, "-") end schema.ldap_syntaxes.each do |syntax| register_syntax(syntax, "-") end end end private def extract_options(configuration) configuration = configuration.dup classes = configuration.delete(:classes) || ["ActiveLdap::Base"] @classes_re = /class.*#{Regexp.union(*classes)}/ # @extract_schema = configuration.delete(:extract_schema) configuration end def default_configuration { :host => "127.0.0.1", :allow_anonymous => true, :extract_schema => false, } end def ensure_configuration(configuration) configuration ||= ENV["RAILS_ENV"] || {} if configuration.is_a?(String) if File.exists?(configuration) require 'erb' require 'yaml' erb = ERB.new(File.read(configuration)) erb.filename = configuration configuration = YAML.load(erb.result) else ENV["RAILS_ENV"] = configuration require 'config/environment' configuration = ActiveLdap::Base.configurations[configuration] end end if defined?(Rails) rails_configuration = ActiveLdap::Base.configurations[Rails.env] configuration = rails_configuration.merge(configuration) end configuration = configuration.symbolize_keys end def load_constants(file) old_constants = Object.constants begin eval(File.read(file), TOPLEVEL_BINDING, file) rescue format = _("Ignored '%{file}'. Solve dependencies first.") $stderr.puts(format % {:file => file}) $stderr.puts($!) end Object.constants - old_constants end def extract(targets) @targets = {} targets.each do |id, *file_infos| @targets[id] = file_infos end yield @targets.collect do |id, file_infos| [id, *file_infos.uniq] end.sort_by do |id,| id end end def register(id, file) file_info = "#{file}:-" @targets[id] ||= [] @targets[id] << file_info end def register_object_class(object_class, file) [object_class.name, *object_class.aliases].each do |name| register(ActiveLdap::Base.human_object_class_name_msgid(name), file) end if object_class.description msgid = ActiveLdap::Base.human_object_class_description_msgid(object_class) register(msgid, file) end (object_class.must(false) + object_class.may(false)).each do |attribute| register_attribute(attribute, file) end object_class.super_classes.each do |super_class| register_object_class(super_class, file) end end def register_attribute(attribute, file) [attribute.name, *attribute.aliases].each do |name| msgid = ActiveLdap::Base.human_attribute_name_msgid(name) register(msgid, file) if msgid end if attribute.description msgid = ActiveLdap::Base.human_attribute_description_msgid(attribute) register(msgid, file) end end def register_syntax(syntax, file) msgid = ActiveLdap::Base.human_syntax_name_msgid(syntax) register(msgid, file) if syntax.description msgid = ActiveLdap::Base.human_syntax_description_msgid(syntax) register(msgid, file) end end end end end activeldap-5.2.4/lib/active_ldap/operations.rb0000644000004100000410000004661413464071751021442 0ustar www-datawww-datamodule ActiveLdap module Operations class << self def included(base) super base.class_eval do extend(Common) extend(Find) extend(LDIF) extend(Delete) extend(ClassOnlyDelete) extend(Update) extend(ClassOnlyUpdate) include(Common) include(Find) include(LDIF) include(Delete) include(Update) end end end module Common VALID_SEARCH_OPTIONS = [:attribute, :value, :filter, :prefix, :classes, :scope, :limit, :attributes, :sort_by, :order, :connection, :base, :offset] def search(options={}, &block) validate_search_options(options) attr = options[:attribute] value = options[:value] || '*' filter = options[:filter] prefix = options[:prefix] classes = options[:classes] requested_attributes = options[:attributes] value = value.first if value.is_a?(Array) and value.first.size == 1 _attr = nil _prefix = nil if attr.nil? or attr == dn_attribute _attr, value, _prefix = split_search_value(value) end attr ||= _attr || ensure_search_attribute prefix ||= _prefix filter ||= [attr, value] filter = [:and, filter, *object_class_filters(classes)] _base = options[:base] ? [options[:base]] : [prefix, base] _base = prepare_search_base(_base) if options.has_key?(:ldap_scope) message = _(":ldap_scope search option is deprecated. " \ "Use :scope instead.") ActiveSupport::Deprecation.warn(message) options[:scope] ||= options[:ldap_scope] end search_options = { :base => _base, :scope => options[:scope] || scope, :filter => filter, :limit => options[:limit], :attributes => requested_attributes, :sort_by => options[:sort_by] || sort_by, :order => options[:order] || order, } options[:connection] ||= connection values = [] requested_all_attributes_p = (requested_attributes.nil? or requested_attributes.include?('*')) options[:connection].search(search_options) do |dn, attrs| attributes = {} attrs.each do |key, _value| if requested_all_attributes_p or requested_attributes.include?(key) normalized_attribute, normalized_value = normalize_attribute_options(key, _value) attributes[normalized_attribute] ||= [] attributes[normalized_attribute].concat(normalized_value) else next end end values << [dn, attributes] end values = values.collect {|_value| yield(_value)} if block_given? values end def exist?(dn, options={}) attr, value, prefix = split_search_value(dn) options_for_leaf = { :attribute => attr, :value => value, :prefix => prefix, :limit => 1, } attribute = attr || ensure_search_attribute options_for_non_leaf = { :attribute => attr, :value => value, :prefix => ["#{attribute}=#{value}", prefix].compact.join(","), :limit => 1, :scope => :base, } !search(options_for_leaf.merge(options)).empty? or !search(options_for_non_leaf.merge(options)).empty? end alias_method :exists?, :exist? def count(options={}) search(options).size end private def validate_search_options(options) options.assert_valid_keys(VALID_SEARCH_OPTIONS) end def extract_options_from_args!(args) args.last.is_a?(Hash) ? args.pop : {} end def ensure_search_attribute(*candidates) default_search_attribute || "objectClass" end def ensure_dn_attribute(target) "#{dn_attribute}=" + target.gsub(/^\s*#{Regexp.escape(dn_attribute)}\s*=\s*/i, '') end def ensure_base(target) [truncate_base(target), base.to_s].reject do |component| component.blank? end.join(',') end def truncate_base(target) return nil if target.blank? return target if base.nil? parsed_target = nil if target.is_a?(DN) parsed_target = target elsif /,/ =~ target begin parsed_target = DN.parse(target) rescue DistinguishedNameInvalid end end return target if parsed_target.nil? begin (parsed_target - base).to_s rescue ArgumentError target end end def prepare_search_base(components) components.compact.collect do |component| case component when String component when DN component.to_s else DN.new(*component).to_s end end.reject{|x| x.empty?}.join(",") end def object_class_filters(classes=nil) expected_classes = (classes || required_classes).collect do |name| Escape.ldap_filter_escape(name) end unexpected_classes = excluded_classes.collect do |name| Escape.ldap_filter_escape(name) end filters = [] unless expected_classes.empty? filters << ["objectClass", "=", *expected_classes] end unless unexpected_classes.empty? filters << [:not, [:or, ["objectClass", "=", *unexpected_classes]]] end filters end def split_search_value(value) attr = prefix = nil begin dn = DN.parse(value) attr, value = dn.rdns.first.to_a.first rest = dn.rdns[1..-1] prefix = DN.new(*rest).to_s unless rest.empty? rescue DistinguishedNameInputInvalid return [attr, value, prefix] rescue DistinguishedNameInvalid begin dn = DN.parse("DUMMY=#{value}") _, value = dn.rdns.first.to_a.first rest = dn.rdns[1..-1] prefix = DN.new(*rest).to_s unless rest.empty? rescue DistinguishedNameInvalid end end prefix = nil if prefix == base prefix = truncate_base(prefix) if prefix [attr, value, prefix] end end module Find # find # # Finds the first match for value where |value| is the value of some # |field|, or the wildcard match. This is only useful for derived classes. # usage: Subclass.find(:all, :attribute => "cn", :value => "some*val") # Subclass.find(:all, 'some*val') def find(*args) options = extract_options_from_args!(args) args = [:first] if args.empty? and !options.empty? case args.first when :first options[:value] ||= args[1] find_initial(options) when :last options[:value] ||= args[1] find_last(options) when :all options[:value] ||= args[1] find_every(options) else find_from_dns(args, options) end end # A convenience wrapper for find(:first, # *args). You can pass in all the same arguments # to this method as you can to find(:first). def first(*args) find(:first, *args) end # A convenience wrapper for find(:last, # *args). You can pass in all the same arguments # to this method as you can to find(:last). def last(*args) find(:last, *args) end # This is an alias for find(:all). You can pass in # all the same arguments to this method as you can # to find(:all) def all(*args) find(:all, *args) end private def find_initial(options) find_every(options.merge(:limit => 1)).first end def find_last(options) order = options[:order] || self.order || 'ascend' order = normalize_sort_order(order) == :ascend ? :descend : :ascend find_initial(options.merge(:order => order)) end def normalize_sort_order(value) case value.to_s when /\Aasc(?:end)?\z/i :ascend when /\Adesc(?:end)?\z/i :descend else raise ArgumentError, _("Invalid order: %s") % value.inspect end end def find_every(options) options = options.dup sort_by = options.delete(:sort_by) || self.sort_by order = options.delete(:order) || self.order limit = options.delete(:limit) if sort_by or order offset = options.delete(:offset) || offset options[:attributes] = options.delete(:attributes) || ['*'] options[:attributes] |= ['objectClass'] if options.delete(:include_operational_attributes) options[:attributes] |= ["+"] end results = search(options).collect do |dn, attrs| instantiate([dn, attrs, {:connection => options[:connection]}]) end return results if sort_by.nil? and order.nil? sort_by ||= "dn" if sort_by.downcase == "dn" results = results.sort_by {|result| DN.parse(result.dn)} else results = results.sort_by {|result| result.send(sort_by)} end results.reverse! if normalize_sort_order(order || "ascend") == :descend results = results[offset, results.size] if offset results = results[0, limit] if limit results end def find_from_dns(dns, options) expects_array = dns.first.is_a?(Array) return [] if expects_array and dns.first.empty? dns = dns.flatten.compact.uniq case dns.size when 0 raise EntryNotFound, _("Couldn't find %s without a DN") % name when 1 result = find_one(dns.first, options) expects_array ? [result] : result else find_some(dns, options) end end def find_one(dn, options) attr, value, prefix = split_search_value(dn) filter = [attr || ensure_search_attribute, Escape.ldap_filter_escape(value)] filter = [:and, filter, options[:filter]] if options[:filter] options = {:prefix => prefix}.merge(options.merge(:filter => filter)) result = find_initial(options) if result result else args = [self.is_a?(Class) ? name : self.class.name, dn] if options[:filter] format = _("Couldn't find %s: DN: %s: filter: %s") args << options[:filter].inspect else format = _("Couldn't find %s: DN: %s") end raise EntryNotFound, format % args end end def find_some(dns, options) dn_filters = dns.collect do |dn| attr, value, prefix = split_search_value(dn) attr ||= ensure_search_attribute filter = [attr, value] if prefix filter = [:and, filter, [dn, "*,#{Escape.ldap_filter_escape(prefix)},#{base}"]] end filter end filter = [:or, *dn_filters] filter = [:and, filter, options[:filter]] if options[:filter] result = find_every(options.merge(:filter => filter)) if result.size == dns.size result else args = [self.is_a?(Class) ? name : self.class.name, dns.join(", ")] if options[:filter] format = _("Couldn't find all %s: DNs (%s): filter: %s") args << options[:filter].inspect else format = _("Couldn't find all %s: DNs (%s)") end raise EntryNotFound, format % args end end def ensure_dn(target) attr, value, prefix = split_search_value(target) "#{attr || dn_attribute}=#{value},#{prefix || base}" end end module LDIF def dump(options={}) ldif = Ldif.new options = {:base => base, :scope => scope}.merge(options) options[:connection] ||= connection options[:connection].search(options) do |dn, attributes| ldif << Ldif::Record.new(dn, attributes) end return "" if ldif.records.empty? ldif.to_s end def to_ldif_record(dn, attributes) Ldif::Record.new(dn, attributes) end def to_ldif(dn, attributes) Ldif.new([to_ldif_record(dn, attributes)]).to_s end def load(ldif, options={}) return if ldif.blank? Ldif.parse(ldif).each do |record| record.load(self, options) end end module ContentRecordLoadable def load(operator, options) operator.add_entry(dn, attributes, options) end end Ldif::ContentRecord.send(:include, ContentRecordLoadable) module AddRecordLoadable def load(operator, options) entries = attributes.collect do |key, value| [:add, key, value] end options = {:controls => controls}.merge(options) operator.modify_entry(dn, entries, options) end end Ldif::AddRecord.send(:include, AddRecordLoadable) module DeleteRecordLoadable def load(operator, options) operator.delete_entry(dn, {:controls => controls}.merge(options)) end end Ldif::DeleteRecord.send(:include, DeleteRecordLoadable) module ModifyNameRecordLoadable def load(operator, options) operator.modify_rdn_entry(dn, new_rdn, delete_old_rdn?, new_superior, {:controls => controls}.merge(options)) end end Ldif::ModifyNameRecord.send(:include, ModifyNameRecordLoadable) module ModifyRecordLoadable def load(operator, options) modify_entries = operations.inject([]) do |result, operation| result + operation.to_modify_entries end return if modify_entries.empty? operator.modify_entry(dn, modify_entries, {:controls => controls}.merge(options)) end module AddOperationModifiable def to_modify_entries attributes.collect do |key, value| [:add, key, value] end end end Ldif::ModifyRecord::AddOperation.send(:include, AddOperationModifiable) module DeleteOperationModifiable def to_modify_entries return [[:delete, full_attribute_name, []]] if attributes.empty? attributes.collect do |key, value| [:delete, key, value] end end end Ldif::ModifyRecord::DeleteOperation.send(:include, DeleteOperationModifiable) module ReplaceOperationModifiable def to_modify_entries return [[:replace, full_attribute_name, []]] if attributes.empty? attributes.collect do |key, value| [:replace, key, value] end end end Ldif::ModifyRecord::ReplaceOperation.send(:include, ReplaceOperationModifiable) end Ldif::ModifyRecord.send(:include, ModifyRecordLoadable) end module Delete def destroy_all(options_or_filter=nil, deprecated_options=nil) if deprecated_options.nil? if options_or_filter.is_a?(String) options = {:filter => options_or_filter} else options = (options_or_filter || {}).dup end else options = deprecated_options.merge(:filter => options_or_filter) end find(:all, options).sort_by do |target| target.dn end.each do |target| target.destroy end end def delete_all(options_or_filter=nil, deprecated_options=nil) if deprecated_options.nil? if options_or_filter.is_a?(String) options = {:filter => options_or_filter} else options = (options_or_filter || {}).dup end else options = deprecated_options.merge(:filter => options_or_filter) end targets = search(options).collect do |dn, attributes| dn end.sort_by do |dn| dn.upcase.reverse end.reverse delete_entry(targets, options) end def delete_entry(dn, options={}) options[:connection] ||= connection begin options[:connection].delete(dn, options) rescue Error format = _("Failed to delete LDAP entry: <%s>: %s") raise DeleteError.new(format % [dn.inspect, $!.message]) end end end module ClassOnlyDelete def destroy(targets, options={}) targets = [targets] unless targets.is_a?(Array) targets.each do |target| find(target, options).destroy end end def delete(targets, options={}) targets = [targets] unless targets.is_a?(Array) targets = targets.collect do |target| ensure_dn_attribute(ensure_base(target)) end delete_entry(targets, options) end end module Update def add_entry(dn, attributes, options={}) unnormalized_attributes = attributes.collect do |key, value| [:add, key, unnormalize_attribute(key, value)] end options[:connection] ||= connection options[:connection].add(dn, unnormalized_attributes, options) end def modify_entry(dn, attributes, options={}) return if attributes.empty? unnormalized_attributes = attributes.collect do |type, key, value| [type, key, unnormalize_attribute(key, value)] end options[:connection] ||= connection options[:connection].modify(dn, unnormalized_attributes, options) end def modify_rdn_entry(dn, new_rdn, delete_old_rdn, new_superior, options={}) options[:connection] ||= connection options[:connection].modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options) end def update_all(attributes, filter=nil, options={}) search_options = options.dup if filter if filter.is_a?(String) and /[=\(\)&\|]/ !~ filter search_options = search_options.merge(:value => filter) else search_options = search_options.merge(:filter => filter) end end targets = search(search_options).collect do |dn, attrs| dn end unnormalized_attributes = attributes.collect do |name, value| normalized_name, normalized_value = normalize_attribute(name, value) [:replace, normalized_name, unnormalize_attribute(normalized_name, normalized_value)] end options[:connection] ||= connection conn = options[:connection] targets.each do |dn| conn.modify(dn, unnormalized_attributes, options) end end end module ClassOnlyUpdate def update(dn, attributes, options={}) if dn.is_a?(Array) i = -1 dns = dn dns.collect do |_dn| i += 1 update(_dn, attributes[i], options) end else object = find(dn, options) object.update_attributes(attributes) object end end end end end activeldap-5.2.4/lib/active_ldap/populate.rb0000644000004100000410000000376313464071751021106 0ustar www-datawww-datamodule ActiveLdap module Populate module_function def ensure_base(base_class=nil, options={}) base_class ||= Base return unless base_class.search(:scope => :base).empty? dc_base_class = options[:dc_base_class] || base_class ou_base_class = options[:ou_base_class] || base_class base_dn = DN.parse(base_class.base) suffixes = [] base_dn.rdns.reverse_each do |rdn| name, value = rdn.to_a[0] prefix = suffixes.join(",") suffixes.unshift("#{name}=#{value}") begin case name.downcase when "dc" ensure_dc(value, prefix, dc_base_class) when "ou" ensure_ou(value, :base => prefix, :base_class => ou_base_class) end rescue ActiveLdap::OperationNotPermitted end end end def ensure_ou(name, options={}) if options.is_a?(Class) base_class = options options = {} else base_class = options[:base_class] || Base end name = name.to_s if name.is_a?(DN) name = name.gsub(/\Aou\s*=\s*/i, '') ou_class = Class.new(base_class) ou_class.ldap_mapping(:dn_attribute => "ou", :prefix => "", :classes => ["top", "organizationalUnit"]) ou_class.base = options[:base] return if ou_class.exist?(name) ou_class.new(name).save! end def ensure_dc(name, prefix, base_class=nil) base_class ||= Base name = name.to_s if name.is_a?(DN) name = name.gsub(/\Adc\s*=\s*/i, '') dc_class = Class.new(base_class) dc_class.ldap_mapping(:dn_attribute => "dc", :prefix => "", :scope => :base, :classes => ["top", "dcObject", "organization"]) dc_class.base = prefix return if dc_class.exist?(name) dc = dc_class.new(name) dc.o = dc.dc dc.save! end end end activeldap-5.2.4/lib/active_ldap/validations.rb0000644000004100000410000001532613464071751021570 0ustar www-datawww-datamodule ActiveLdap module Validations extend ActiveSupport::Concern include ActiveModel::Validations module ClassMethods def attribute_method?(attribute) normalized_attribute = entry_attribute.normalize(attribute) normalized_attribute and normalized_attribute != "objectClass" end private def entry_attribute @entry_attribute ||= connection.entry_attribute(classes.collect(&:name)) end end included do alias_method :new_record?, :new_entry? class << self unless method_defined?(:human_attribute_name_with_gettext) def human_attribute_name_with_gettext(attribute_key_name, options={}) logger.warn("options was ignored.") unless options.empty? s_("#{self}|#{attribute_key_name.to_s.humanize}") end end end class_local_attr_accessor true, :validation_skip_attributes remove_method :validation_skip_attributes self.validation_skip_attributes = [] validate :validate_duplicated_dn_creation, :on => :create validate :validate_duplicated_dn_rename, :on => :update validate :validate_dn validate :validate_excluded_classes validate :validate_required_ldap_values validate :validate_ldap_values end def validation_skip_attributes @validation_skip_attributes ||= [] end def validation_skip_attributes=(attributes) @validation_skip_attributes = attributes end def valid?(context = nil) context ||= (new_entry? ? :create : :update) output = super(context) errors.empty? && output end def save(*) valid? ? super : false end def save!(*) valid? ? super : raise(EntryInvalid.new(self)) end private def format_validation_message(format, parameters) format % parameters end def validate_duplicated_dn_creation _dn = nil begin _dn = dn rescue DistinguishedNameInvalid, DistinguishedNameNotSetError return end if _dn and exist? format = _("is duplicated: %s") message = format_validation_message(format, _dn) errors.add("distinguishedName", message) end end def validate_duplicated_dn_rename _dn_attribute = dn_attribute_with_fallback original_dn_value = @ldap_data[_dn_attribute] current_dn_value = @data[_dn_attribute] return if original_dn_value == current_dn_value return if original_dn_value == [current_dn_value] _dn = nil begin _dn = dn rescue DistinguishedNameInvalid, DistinguishedNameNotSetError return end if _dn and exist? format = _("is duplicated: %s") message = format_validation_message(format, _dn) errors.add("distinguishedName", message) end end def validate_dn dn rescue DistinguishedNameInvalid format = _("is invalid: %s") message = format_validation_message(format, $!.message) errors.add("distinguishedName", message) rescue DistinguishedNameNotSetError format = _("isn't set: %s") message = format_validation_message(format, $!.message) errors.add("distinguishedName", message) end def validate_excluded_classes excluded_classes = self.class.excluded_classes return if excluded_classes.empty? _schema = schema _classes = classes.collect do |name| _schema.object_class(name) end unexpected_classes = excluded_classes.inject([]) do |classes, name| excluded_class = _schema.object_class(name) if _classes.include?(excluded_class) classes << excluded_class end classes end return if unexpected_classes.empty? names = unexpected_classes.collect do |object_class| self.class.human_object_class_name(object_class) end format = n_("has excluded value: %s", "has excluded values: %s", names.size) message = format_validation_message(format, names.join(", ")) errors.add("objectClass", message) end # validate_required_ldap_values # # Basic validation: # - Verify that every 'MUST' specified in the schema has a value defined def validate_required_ldap_values _schema = nil @validation_skip_attributes ||= [] _validation_skip_attributes = @validation_skip_attributes + (self.class.validation_skip_attributes || []) # Make sure all MUST attributes have a value entry_attribute.object_classes.each do |object_class| object_class.must.each do |required_attribute| # Normalize to ensure we catch schema problems # needed? real_name = to_real_attribute_name(required_attribute.name, true) raise UnknownAttribute.new(required_attribute) if real_name.nil? next if required_attribute.read_only? next if _validation_skip_attributes.include?(real_name) value = @data[real_name] next unless self.class.blank_value?(value) _schema ||= schema aliases = required_attribute.aliases.collect do |name| self.class.human_attribute_name(name) end args = [self.class.human_object_class_name(object_class)] if aliases.empty? format = _("is required attribute by objectClass '%s'") else format = _("is required attribute by objectClass " \ "'%s': aliases: %s") args << aliases.join(', ') end message = format_validation_message(format, args) errors.add(real_name, message) end end end def validate_ldap_values entry_attribute.schemata.each do |name, attribute| value = self[name] # Is it really proper location for setting encoding? attribute.apply_encoding(value) next if self.class.blank_value?(value) validate_ldap_value(attribute, name, value) end end def validate_ldap_value(attribute, name, value) failed_reason, option = attribute.validate(value) return if failed_reason.nil? if attribute.binary? inspected_value = _("") else inspected_value = self.class.human_readable_format(value) end params = [inspected_value, self.class.human_syntax_description(attribute.syntax), failed_reason] if option format = _("(%s) has invalid format: %s: required syntax: %s: %s") else format = _("has invalid format: %s: required syntax: %s: %s") end params.unshift(option) if option message = format_validation_message(format, params) errors.add(name, message) end end end activeldap-5.2.4/lib/active_ldap/associations.rb0000644000004100000410000001630113464071751021744 0ustar www-datawww-datarequire 'active_ldap/association/belongs_to' require 'active_ldap/association/belongs_to_many' require 'active_ldap/association/has_many' require 'active_ldap/association/has_many_wrap' module ActiveLdap # Associations # # Associations provides the class methods needed for # the extension classes to create methods using # belongs_to and has_many module Associations def self.append_features(base) super base.extend(ClassMethods) base.class_attribute(:associations) base.associations ||= [] end module ClassMethods def set_associated_class(name, klass) @associated_classes ||= {} @associated_classes[name.to_s] = klass end def associated_class(name) @associated_classes[name.to_s] end # belongs_to # # This defines a method for an extension class map its DN key # attribute value on to multiple items which reference it by # |:foreign_key| in the other LDAP entry covered by class # |:class_name|. # # Example: # belongs_to :groups, :class_name => "Group", # :many => "memberUid" # Group#memberUid # # :primary_key => "uid" # User#uid # ## deprecated since 1.1.0. Use :primary_key instead. # ## :foreign_key => "uid" # User#uid # # dn attribute value is used by default # belongs_to :primary_group, :class_name => "Group", # :foreign_key => "gidNumber", # User#gidNumber # :primary_key => "gidNumber" # Group#gidNumber # def belongs_to(association_id, options={}) validate_belongs_to_options(options) klass = options[:class] klass ||= (options[:class_name] || association_id.to_s).classify foreign_key = options[:foreign_key] primary_key = options[:primary_key] many = options[:many] set_associated_class(association_id, klass) opts = { :association_id => association_id, :foreign_key_name => foreign_key, :primary_key_name => primary_key, :many => many, :extend => options[:extend], } if opts[:many] association_class = Association::BelongsToMany foreign_key_name = opts[:foreign_key_name] if foreign_key_name message = _(":foreign_key belongs_to(:many) option is " \ "deprecated since 1.1.0. Use :primary_key instead.") ActiveSupport::Deprecation.warn(message) opts[:primary_key_name] ||= foreign_key_name end opts[:primary_key_name] ||= dn_attribute else association_class = Association::BelongsTo opts[:foreign_key_name] ||= "#{association_id}_id" before_save do if instance_variable_defined?(:"@#{association_id}") association = instance_variable_get(:"@#{association_id}") if association and association.updated? self[association.__send__(:primary_key)] = association[opts[:foreign_key_name]] end end end end association_accessor(association_id) do |target| association_class.new(target, opts) end end # has_many # # This defines a method for an extension class expand an # existing multi-element attribute into ActiveLdap objects. # This discards any calls which result in entries that # don't exist in LDAP! # # Example: # has_many :primary_members, :class_name => "User", # :primary_key => "gidNumber", # Group#gidNumber # :foreign_key => "gidNumber" # User#gidNumber # ## deprecated since 1.1.0. Those options # ## are inverted. # # :primary_key => "gidNumber", # User#gidNumber # # :foreign_key => "gidNumber" # Group#gidNumber # has_many :members, :class_name => "User", # :wrap => "memberUid" # Group#memberUid def has_many(association_id, options = {}) validate_has_many_options(options) klass = options[:class] klass ||= (options[:class_name] || association_id.to_s).classify foreign_key = options[:foreign_key] primary_key = options[:primary_key] set_associated_class(association_id, klass) opts = { :association_id => association_id, :foreign_key_name => foreign_key, :primary_key_name => primary_key, :wrap => options[:wrap], :extend => options[:extend], } if opts[:wrap] association_class = Association::HasManyWrap else association_class = Association::HasMany primary_key_name = opts[:primary_key_name] foreign_key_name = opts[:foreign_key_name] if primary_key_name != foreign_key_name and primary_key_name != "dn" and !new.have_attribute?(primary_key_name) message = _(":primary_key and :foreign_key has_many options are " \ "inverted their mean since 1.1.0. Please invert them.") ActiveSupport::Deprecation.warn(message) opts[:foreign_key_name] = primary_key_name opts[:primary_key_name] = foreign_key_name end end association_accessor(association_id) do |target| association_class.new(target, opts) end end private def association_accessor(name, &make_association) define_method("__make_#{name}") do make_association.call(self) end associations << name association_reader(name, &make_association) association_writer(name, &make_association) end def association_reader(name, &make_association) class_eval(<<-EOM, __FILE__, __LINE__ + 1) def #{name} @#{name} ||= __make_#{name} end EOM end def association_writer(name, &make_association) class_eval(<<-EOM, __FILE__, __LINE__ + 1) def #{name}=(new_value) association = defined?(@#{name}) ? @#{name} : nil association ||= __make_#{name} association.replace(new_value) @#{name} = new_value.nil? ? nil : association @#{name} end EOM end VALID_BELONGS_TO_OPTIONS = [:class, :class_name, :foreign_key, :primary_key, :many, :extend] def validate_belongs_to_options(options) options.assert_valid_keys(VALID_BELONGS_TO_OPTIONS) end VALID_HAS_MANY_OPTIONS = [:class, :class_name, :foreign_key, :primary_key, :wrap, :extend] def validate_has_many_options(options) options.assert_valid_keys(VALID_HAS_MANY_OPTIONS) end end def clear_association_cache return if new_record? (self.class.associations || []).each do |association| instance_variable_set("@#{association}", nil) end end end module Association autoload :Children, 'active_ldap/association/children' end end activeldap-5.2.4/lib/active_ldap/object_class.rb0000644000004100000410000000631513464071751021704 0ustar www-datawww-datamodule ActiveLdap module ObjectClass def self.included(base) base.extend(ClassMethods) end module ClassMethods def classes required_classes.collect do |name| schema.object_class(name) end end end def add_class(*target_classes) replace_class(classes + target_classes) end def ensure_recommended_classes add_class(self.class.recommended_classes) end def remove_class(*target_classes) replace_class(classes - target_classes) end def replace_class(*target_classes) new_classes = target_classes.flatten.compact.uniq assert_object_classes(new_classes) if new_classes.sort != classes.sort original_attributes = must + may set_attribute('objectClass', new_classes) clear_object_class_based_cache new_attributes = must + may removed_attributes = original_attributes - new_attributes clear_removed_attributes_data(removed_attributes) end end alias_method(:classes=, :replace_class) def classes (get_attribute('objectClass', true) || []).dup end private def assert_object_classes(new_classes) assert_valid_object_class_value_type(new_classes) assert_valid_object_class_value(new_classes) assert_have_all_required_classes(new_classes) end def assert_valid_object_class_value_type(new_classes) invalid_classes = new_classes.reject do |new_class| new_class.is_a?(String) end unless invalid_classes.empty? format = _("Value in objectClass array is not a String: %s") invalid_classes_info = invalid_classes.collect do |invalid_class| "#{invalid_class.class}: #{invalid_class.inspect}" end.join(", ") raise TypeError, format % invalid_classes_info end end def assert_valid_object_class_value(new_classes) _schema = schema invalid_classes = new_classes.reject do |new_class| !_schema.object_class(new_class).id.nil? end unless invalid_classes.empty? format = _("unknown objectClass in LDAP server: %s") message = format % invalid_classes.join(', ') raise ObjectClassError, message end end def assert_have_all_required_classes(new_classes) _schema = schema normalized_new_classes = new_classes.collect(&:downcase) required_classes = self.class.required_classes required_classes = required_classes.reject do |required_class_name| normalized_new_classes.include?(required_class_name.downcase) or (normalized_new_classes.find do |new_class| required_class = _schema.object_class(required_class_name) _schema.object_class(new_class).super_class?(required_class) end) end unless required_classes.empty? format = _("Can't remove required objectClass: %s") required_class_names = required_classes.collect do |required_class| required_class = _schema.object_class(required_class) self.class.human_object_class_name(required_class) end message = format % required_class_names.join(", ") raise RequiredObjectClassMissed, message end end end end activeldap-5.2.4/lib/active_ldap/attribute_methods/0000755000004100000410000000000013464071751022445 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap/attribute_methods/dirty.rb0000644000004100000410000000165713464071751024136 0ustar www-datawww-data# module ActiveLdap module AttributeMethods module Dirty extend ActiveSupport::Concern include ActiveModel::Dirty # Attempts to +save+ the record and clears changed attributes if successful. def save(*) #:nodoc: succeeded = super if succeeded changes_applied end succeeded end # Attempts to save! the record and clears changed attributes if successful. def save!(*) #:nodoc: super.tap do changes_applied end end # reload the record and clears changed attributes. def reload(*) #:nodoc: super.tap do clear_changes_information end end private def set_attribute(name, value) if name and name != "objectClass" attribute_will_change!(name) unless value == get_attribute(name) end super end end end end activeldap-5.2.4/lib/active_ldap/attribute_methods/query.rb0000644000004100000410000000127713464071751024146 0ustar www-datawww-data# module ActiveLdap module AttributeMethods module Query extend ActiveSupport::Concern included do attribute_method_suffix '?' end private def get_attribute_as_query(name, force_array=false) name, value = get_attribute_before_type_cast(name, force_array) if force_array value.collect {|x| !false_value?(x)} else !false_value?(value) end end def false_value?(value) value.nil? or value == false or value == [] or value == "false" or value == "FALSE" or value == "" end def attribute?(attr) return get_attribute_as_query(attr) end end end end activeldap-5.2.4/lib/active_ldap/attribute_methods/before_type_cast.rb0000644000004100000410000000104513464071751026307 0ustar www-datawww-datamodule ActiveLdap module AttributeMethods module BeforeTypeCast extend ActiveSupport::Concern included do attribute_method_suffix '_before_type_cast' end private def attribute_before_type_cast(attr) get_attribute_before_type_cast(attr)[1] end def get_attribute_before_type_cast(name, force_array=false) name = to_real_attribute_name(name) value = @data[name] value = [] if value.nil? [name, array_of(value, force_array)] end end end end activeldap-5.2.4/lib/active_ldap/attribute_methods/write.rb0000644000004100000410000000167113464071751024131 0ustar www-datawww-datamodule ActiveLdap module AttributeMethods module Write extend ActiveSupport::Concern included do attribute_method_suffix '=' end private def attribute=(attr, *args) return set_attribute(attr, args.first) end # set_attribute # # Set the value of the attribute called by method_missing? def set_attribute(name, value) real_name = to_real_attribute_name(name) _dn_attribute = nil valid_dn_attribute = true begin _dn_attribute = dn_attribute rescue DistinguishedNameInvalid valid_dn_attribute = false end if valid_dn_attribute and real_name == _dn_attribute real_name, value = register_new_dn_attribute(real_name, value) end raise UnknownAttribute.new(name) if real_name.nil? @data[real_name] = value @simplified_data = nil end end end end activeldap-5.2.4/lib/active_ldap/attribute_methods/read.rb0000644000004100000410000000220013464071751023677 0ustar www-datawww-datamodule ActiveLdap module AttributeMethods module Read extend ActiveSupport::Concern private def attribute(attr, *args) return get_attribute(attr, args.first) end def _read_attribute(name) get_attribute(name) end # get_attribute # # Return the value of the attribute called by method_missing? def get_attribute(name, force_array=false) name, value = get_attribute_before_type_cast(name, force_array) return value if name.nil? attribute = schema.attribute(name) type_cast(attribute, value) end def type_cast(attribute, value) case value when Hash result = {} value.each do |option, val| result[option] = type_cast(attribute, val) end if result.size == 1 and result.has_key?("binary") result["binary"] else result end when Array value.collect do |val| type_cast(attribute, val) end else attribute.type_cast(value) end end end end end activeldap-5.2.4/lib/active_ldap/get_text.rb0000644000004100000410000000046413464071751021073 0ustar www-datawww-datarequire "gettext" module ActiveLdap class << self def get_text_supported? true end end module GetTextSupport class << self def included(base) base.class_eval do include(GetText) bindtextdomain("active-ldap") end end end end end activeldap-5.2.4/lib/active_ldap/persistence.rb0000644000004100000410000000457013464071751021576 0ustar www-datawww-datamodule ActiveLdap module Persistence # new_entry? # # Return whether the entry is new entry in LDAP or not def new_entry? @new_entry end # Return whether the entry is saved entry or not. def persisted? not new_entry? end # destroy # # Delete this entry from LDAP def destroy # TODO: support deleting relations delete end def delete(options={}) if persisted? default_options = { :connection => connection, } self.class.delete_entry(dn, default_options.merge(options)) end @new_entry = true freeze end # save # # Save and validate this object into LDAP # either adding or replacing attributes # TODO: Relative DN support def save(*) create_or_update end def save!(*) unless create_or_update raise EntryNotSaved, _("entry %s can't be saved") % dn end true end def create_or_update new_entry? ? create : update end def create prepare_data_for_saving do |data, ldap_data| attributes = collect_all_attributes(data) add_entry(dn, attributes) @new_entry = false true end end def update prepare_data_for_saving do |data, ldap_data| new_dn_value, attributes = collect_modified_attributes(ldap_data, data) modify_entry(@original_dn, attributes) if new_dn_value old_dn_base = DN.parse(@original_dn).parent new_dn_base = dn.clone.parent if old_dn_base == new_dn_base new_superior = nil else new_superior = new_dn_base.to_s end modify_rdn_entry(@original_dn, "#{dn_attribute}=#{DN.escape_value(new_dn_value)}", true, new_superior) end true end end def reload clear_association_cache _, attributes = search(:value => id).find do |_dn, _attributes| dn == _dn end if attributes.nil? raise EntryNotFound, _("Can't find DN '%s' to reload") % dn end @ldap_data.update(attributes) classes = extract_object_class!(attributes) self.classes = classes self.attributes = attributes @new_entry = false self end end # Persistence end # ActiveLdap activeldap-5.2.4/lib/active_ldap/adapter/0000755000004100000410000000000013464071751020337 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap/adapter/ldap_ext.rb0000644000004100000410000000743213464071751022472 0ustar www-datawww-datarequire "ldap" require "ldap/ldif" require "ldap/schema" require "ldap/control" module LDAP unless const_defined?(:LDAP_OPT_ERROR_NUMBER) LDAP_OPT_ERROR_NUMBER = 0x0031 end class Mod unless instance_method(:to_s).arity.zero? alias_method :original_to_s, :to_s def to_s inspect end end alias_method :_initialize, :initialize def initialize(op, type, vals) if (VERSION.split(/\./).collect {|x| x.to_i} <=> [0, 9, 7]) <= 0 @op, @type, @vals = op, type, vals # to protect from GC end _initialize(op, type, vals) end end IMPLEMENT_SPECIFIC_ERRORS = {} { 0x51 => "SERVER_DOWN", 0x52 => "LOCAL_ERROR", 0x53 => "ENCODING_ERROR", 0x54 => "DECODING_ERROR", 0x55 => "TIMEOUT", 0x56 => "AUTH_UNKNOWN", 0x57 => "FILTER_ERROR", 0x58 => "USER_CANCELLED", 0x59 => "PARAM_ERROR", 0x5a => "NO_MEMORY", 0x5b => "CONNECT_ERROR", 0x5c => "NOT_SUPPORTED", 0x5d => "CONTROL_NOT_FOUND", 0x5e => "NO_RESULTS_RETURNED", 0x5f => "MORE_RESULTS_TO_RETURN", 0x60 => "CLIENT_LOOP", 0x61 => "REFERRAL_LIMIT_EXCEEDED", }.each do |code, name| IMPLEMENT_SPECIFIC_ERRORS[code] = ActiveLdap::LdapError.define(code, name, self) end class Conn begin instance_method(:search_ext) @@have_search_ext = true rescue NameError @@have_search_ext = false end def search_full(options, &block) base = options[:base] scope = options[:scope] filter = options[:filter] attributes = options[:attributes] limit = options[:limit] || 0 use_paged_results = options[:use_paged_results] if @@have_search_ext if use_paged_results paged_search(base, scope, filter, attributes, limit, &block) else search_ext(base, scope, filter, attributes, false, nil, nil, 0, 0, limit, &block) end else i = 0 search(base, scope, filter, attributes) do |entry| i += 1 block.call(entry) break if 0 < limit and limit <= i end end end def failed? not error_code.zero? end def error_code code = err code = get_option(LDAP_OPT_ERROR_NUMBER) if code.zero? code end def error_message if failed? LDAP.err2string(error_code) else nil end end def assert_error_code return unless failed? code = error_code message = error_message klass = ActiveLdap::LdapError::ERRORS[code] klass ||= IMPLEMENT_SPECIFIC_ERRORS[code] if klass.nil? and message == "Can't contact LDAP server" klass = ActiveLdap::ConnectionError end klass ||= ActiveLdap::LdapError raise klass, message end private def find_paged_results_control(controls) controls.find do |control| control.oid == LDAP::LDAP_CONTROL_PAGEDRESULTS end end def paged_search(base, scope, filter, attributes, limit, &block) # work around a bug with openldap page_size = 126 cookie = "" critical = true loop do ber_string = LDAP::Control.encode(page_size, cookie) control = LDAP::Control.new(LDAP::LDAP_CONTROL_PAGEDRESULTS, ber_string, critical) search_ext(base, scope, filter, attributes, false, [control], nil, 0, 0, limit, &block) control = find_paged_results_control(@controls) break if control.nil? returned_size, cookie = control.decode returned_size = returned_size.to_i page_size = returned_size if returned_size > 0 break if cookie.empty? end end end end activeldap-5.2.4/lib/active_ldap/adapter/jndi_connection.rb0000644000004100000410000001265513464071751024040 0ustar www-datawww-datarequire 'java' java.util.Enumeration.module_eval do include Enumerable def each while has_more_elements yield(next_element) end end end module ActiveLdap module Adapter class JndiConnection HashTable = java.util.Hashtable naming = javax.naming directory = naming.directory ldap = naming.ldap InitialDirContext = directory.InitialDirContext InitialLdapContext = ldap.InitialLdapContext SearchControls = directory.SearchControls ModificationItem = directory.ModificationItem BasicAttributes = directory.BasicAttributes Context = naming.Context StartTlsRequest = ldap.StartTlsRequest Control = ldap.Control CommunicationException = naming.CommunicationException ServiceUnavailableException = naming.ServiceUnavailableException NamingException = naming.NamingException NameNotFoundException = naming.NameNotFoundException module Scope OBJECT = SearchControls::OBJECT_SCOPE ONE_LEVEL = SearchControls::ONELEVEL_SCOPE SUBTREE = SearchControls::SUBTREE_SCOPE end class ModifyRecord directory = javax.naming.directory DirContext = directory.DirContext BasicAttribute = directory.BasicAttribute ADD_ATTRIBUTE = DirContext::ADD_ATTRIBUTE REPLACE_ATTRIBUTE = DirContext::REPLACE_ATTRIBUTE REMOVE_ATTRIBUTE = DirContext::REMOVE_ATTRIBUTE attr_reader :type, :name, :values def initialize(type, name, values, binary) @type = self.class.const_get("#{type.to_s.upcase}_ATTRIBUTE") @name = name @values = values @binary = binary end def binary? @binary end def to_java_modification_item ModificationItem.new(@type, to_java_attribute) end def to_java_attribute attribute = BasicAttribute.new(@name) values = @values values = values.collect(&:to_java_bytes) if binary? values.each do |value| attribute.add(value) end attribute end end def initialize(host, port, method, timeout) @host = host @port = port @method = method @timeout = timeout @context = nil @tls = nil end def unbind @tls.close if @tls @tls = nil @context.close if @context @context = nil end def bound? not @context.nil? end def sasl_bind(bind_dn, mechanism, quiet) setup_context(bind_dn, password, mechanism) bound? end def simple_bind(bind_dn, password) setup_context(bind_dn, password, "simple") bound? end def bind_as_anonymous setup_context(nil, nil, "none") bound? end def search(base, scope, filter, attrs, limit) controls = SearchControls.new controls.search_scope = scope controls.count_limit = limit if limit unless attrs.blank? controls.returning_attributes = attrs.to_java(:string) end @context.search(base, filter, controls).each do |result| attributes = {} result.attributes.get_all.each do |attribute| attributes[attribute.get_id] = attribute.get_all.collect do |value| value.is_a?(String) ? value : String.from_java_bytes(value) end end yield([result.name_in_namespace, attributes]) end end def add(dn, records) attributes = BasicAttributes.new records.each do |record| attributes.put(record.to_java_attribute) end @context.create_subcontext(dn, attributes) end def modify(dn, records) items = records.collect(&:to_java_modification_item) @context.modify_attributes(dn, items.to_java(ModificationItem)) end def modify_rdn(dn, new_rdn, delete_old_rdn) # should use mutex delete_rdn_key = "java.naming.ldap.deleteRDN" @context.add_to_environment(delete_rdn_key, delete_old_rdn.to_s) @context.rename(dn, new_rdn) ensure @context.remove_from_environment(delete_rdn_key) end def delete(dn) @context.destroy_subcontext(dn) end private def setup_context(bind_dn, password, authentication) unbind environment = { Context::INITIAL_CONTEXT_FACTORY => "com.sun.jndi.ldap.LdapCtxFactory", Context::PROVIDER_URL => ldap_uri, 'com.sun.jndi.ldap.connect.timeout' => (@timeout * 1000).to_i.to_s, 'com.sun.jndi.ldap.read.timeout' => (@timeout * 1000).to_i.to_s, } environment = HashTable.new(environment) context = InitialLdapContext.new(environment, nil) if @method == :start_tls @tls = context.extended_operation(StartTlsRequest.new) @tls.negotiate end context.add_to_environment(Context::SECURITY_AUTHENTICATION, authentication) if bind_dn context.add_to_environment(Context::SECURITY_PRINCIPAL, bind_dn) end if password context.add_to_environment(Context::SECURITY_CREDENTIALS, password) end context.reconnect(nil) @context = context end def ldap_uri protocol = @method == :ssl ? "ldaps" : "ldap" "#{protocol}://#{@host}:#{@port}/" end end end end activeldap-5.2.4/lib/active_ldap/adapter/base.rb0000644000004100000410000005101413464071751021577 0ustar www-datawww-datarequire 'timeout' require 'active_ldap/schema' require 'active_ldap/entry_attribute' require 'active_ldap/ldap_error' require 'active_ldap/supported_control' module ActiveLdap module Adapter class Base include GetTextSupport VALID_ADAPTER_CONFIGURATION_KEYS = [ :host, :port, :method, :tls_options, :timeout, :retry_on_timeout, :retry_limit, :retry_wait, :bind_dn, :password, :password_block, :try_sasl, :sasl_mechanisms, :sasl_quiet, :allow_anonymous, :store_password, :scope, :sasl_options, :follow_referrals, ] @@row_even = true def initialize(configuration={}) @connection = nil @disconnected = false @bound = false @bind_tried = false @entry_attributes = {} @follow_referrals = nil @configuration = configuration.dup @logger = @configuration.delete(:logger) @configuration.assert_valid_keys(VALID_ADAPTER_CONFIGURATION_KEYS) VALID_ADAPTER_CONFIGURATION_KEYS.each do |name| instance_variable_set("@#{name}", configuration[name]) end @follow_referrals = true if @follow_referrals.nil? @instrumenter = ActiveSupport::Notifications.instrumenter end def connect(options={}) host = options[:host] || @host method = options[:method] || @method || :plain port = options[:port] || @port || ensure_port(method) method = ensure_method(method) @disconnected = false @bound = false @bind_tried = false @connection, @uri, @with_start_tls = yield(host, port, method) prepare_connection(options) bind(options) end def disconnect!(options={}) unbind(options) @connection = @uri = @with_start_tls = nil @disconnected = true end def rebind(options={}) unbind(options) if bound? connect(options) end def bind(options={}) @bind_tried = true bind_dn = ensure_dn_string(options[:bind_dn] || @bind_dn) try_sasl = options.has_key?(:try_sasl) ? options[:try_sasl] : @try_sasl if options.has_key?(:allow_anonymous) allow_anonymous = options[:allow_anonymous] else allow_anonymous = @allow_anonymous end options = options.merge(:allow_anonymous => allow_anonymous) # Rough bind loop: # Attempt 1: SASL if available # Attempt 2: SIMPLE with credentials if password block # Attempt 3: SIMPLE ANONYMOUS if 1 and 2 fail (or pwblock returns '') if try_sasl and sasl_bind(bind_dn, options) @logger.info {_('Bound to %s by SASL as %s') % [target, bind_dn]} elsif simple_bind(bind_dn, options) @logger.info {_('Bound to %s by simple as %s') % [target, bind_dn]} elsif allow_anonymous and bind_as_anonymous(options) @logger.info {_('Bound to %s as anonymous') % target} else message = yield if block_given? message ||= _('All authentication methods for %s exhausted.') % target raise AuthenticationError, message end @bound = true @bound end def unbind(options={}) yield if @connection and (@bind_tried or bound?) @bind_tried = @bound = false end def bind_as_anonymous(options={}) yield end def connecting? !@connection.nil? and !@disconnected end def bound? connecting? and @bound end def schema(options={}) @schema ||= operation(options) do base = options[:base] attrs = options[:attributes] attrs ||= [ 'objectClasses', 'attributeTypes', 'matchingRules', 'matchingRuleUse', 'dITStructureRules', 'dITContentRules', 'nameForms', 'ldapSyntaxes', #'extendedAttributeInfo', # if we need RANGE-LOWER/UPPER. ] base ||= root_dse_values('subschemaSubentry', options)[0] base ||= 'cn=schema' schema = nil search(:base => base, :scope => :base, :filter => '(objectClass=subschema)', :attributes => attrs, :limit => 1) do |dn, attributes| schema = Schema.new(attributes) end schema || Schema.new([]) end end def naming_contexts root_dse_values('namingContexts') end def supported_control @supported_control ||= SupportedControl.new(root_dse_values("supportedControl")) end def entry_attribute(object_classes) @entry_attributes[object_classes.uniq.sort] ||= EntryAttribute.new(schema, object_classes) end def search(options={}) filter = parse_filter(options[:filter]) || 'objectClass=*' attrs = options[:attributes] || [] scope = ensure_scope(options[:scope] || @scope) base = options[:base] limit = options[:limit] || 0 limit = nil if limit <= 0 attrs = attrs.to_a # just in case base = ensure_dn_string(base) begin operation(options) do yield(base, scope, filter, attrs, limit) end rescue LdapError::NoSuchObject, LdapError::InvalidDnSyntax # Do nothing on failure @logger.info do args = [$!.class, $!.message, filter, attrs.inspect] _("Ignore error %s(%s): filter %s: attributes: %s") % args end end end def delete(targets, options={}) targets = [targets] unless targets.is_a?(Array) return if targets.empty? begin operation(options) do targets.each do |target| target = ensure_dn_string(target) begin yield(target) rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess raise OperationNotPermitted, _("%s: %s") % [$!.message, target] end end end rescue LdapError::NoSuchObject raise EntryNotFound, _("No such entry: %s") % target end end def add(dn, entries, options={}) dn = ensure_dn_string(dn) begin operation(options) do yield(dn, entries) end rescue LdapError::NoSuchObject raise EntryNotFound, _("No such entry: %s") % dn rescue LdapError::InvalidDnSyntax raise DistinguishedNameInvalid.new(dn) rescue LdapError::AlreadyExists raise EntryAlreadyExist, _("%s: %s") % [$!.message, dn] rescue LdapError::StrongAuthRequired raise StrongAuthenticationRequired, _("%s: %s") % [$!.message, dn] rescue LdapError::ObjectClassViolation raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn] rescue LdapError::UnwillingToPerform raise OperationNotPermitted, _("%s: %s") % [$!.message, dn] end end def modify(dn, entries, options={}) dn = ensure_dn_string(dn) begin operation(options) do begin yield(dn, entries) rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess raise OperationNotPermitted, _("%s: %s") % [$!.message, target] end end rescue LdapError::UndefinedType raise rescue LdapError::ObjectClassViolation raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn] end end def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={}) dn = ensure_dn_string(dn) operation(options) do yield(dn, new_rdn, delete_old_rdn, new_superior) end end private def ensure_port(method) if method == :ssl URI::LDAPS::DEFAULT_PORT else URI::LDAP::DEFAULT_PORT end end def follow_referrals?(options={}) option_follow_referrals = options[:follow_referrals] if option_follow_referrals.nil? @follow_referrals else option_follow_referrals end end def prepare_connection(options) end def operation(options) retried = false options = options.dup options[:try_reconnect] = true unless options.has_key?(:try_reconnect) try_reconnect = false begin reconnect_if_need(options) try_reconnect = options[:try_reconnect] with_timeout(try_reconnect, options) do yield end rescue ConnectionError if try_reconnect and !retried retried = true @disconnected = true retry else raise end end end def need_credential_sasl_mechanism?(mechanism) not %(GSSAPI EXTERNAL ANONYMOUS).include?(mechanism) end def password(bind_dn, options={}) passwd = options[:password] || @password return passwd if passwd password_block = options[:password_block] || @password_block # TODO: Give a warning to reconnect users with password clearing # Get the passphrase for the first time, or anew if we aren't storing if password_block.respond_to?(:call) passwd = password_block.call(bind_dn) else @logger.error {_('password_block not nil or Proc object. Ignoring.')} return nil end # Store the password for quick reference later if options.has_key?(:store_password) store_password = options[:store_password] else store_password = @store_password end @password = store_password ? passwd : nil passwd end def with_timeout(try_reconnect=true, options={}, &block) n_retries = 0 retry_limit = options[:retry_limit] || @retry_limit begin Timeout.timeout(@timeout, &block) rescue Timeout::Error => e @logger.error {_('Requested action timed out.')} if @retry_on_timeout and (retry_limit < 0 or n_retries <= retry_limit) n_retries += 1 if connecting? retry elsif try_reconnect retry if with_timeout(false, options) {reconnect(options)} end end @logger.error {e.message} raise TimeoutError, e.message end end def sasl_bind(bind_dn, options={}) # Get all SASL mechanisms mechanisms = operation(options) do root_dse_values("supportedSASLMechanisms", options) end if options.has_key?(:sasl_quiet) sasl_quiet = options[:sasl_quiet] else sasl_quiet = @sasl_quiet end sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms sasl_mechanisms.each do |mechanism| next unless mechanisms.include?(mechanism) return true if yield(bind_dn, mechanism, sasl_quiet) end false end def simple_bind(bind_dn, options={}) return false unless bind_dn passwd = password(bind_dn, options) return false unless passwd if passwd.empty? if options[:allow_anonymous] @logger.info {_("Skip simple bind with empty password.")} return false else raise AuthenticationError, _("Can't use empty password for simple bind.") end end begin yield(bind_dn, passwd) rescue LdapError::InvalidDnSyntax raise DistinguishedNameInvalid.new(bind_dn) rescue LdapError::InvalidCredentials false end end def parse_filter(filter, operator=nil) return nil if filter.nil? if !filter.is_a?(String) and !filter.respond_to?(:collect) filter = filter.to_s end case filter when String parse_filter_string(filter) when Hash components = filter.sort_by {|k, v| k.to_s}.collect do |key, value| construct_component(key, value, operator) end construct_filter(components, operator) else operator, components = normalize_array_filter(filter, operator) components = construct_components(components, operator) construct_filter(components, operator) end end def parse_filter_string(filter) if /\A\s*\z/.match(filter) nil else if filter[0, 1] == "(" filter else "(#{filter})" end end end def normalize_array_filter(filter, operator=nil) filter_operator, *components = filter if filter_logical_operator?(filter_operator) operator = filter_operator else components.unshift(filter_operator) components = [components] unless filter_operator.is_a?(Array) end [operator, components] end def extract_filter_value_options(value) options = {} if value.is_a?(Array) case value[0] when Hash options = value[0] value = value[1] when "=", "~=", "<=", ">=" options[:operator] = value[0] if value.size > 2 value = value[1..-1] else value = value[1] end end end [value, options] end def construct_components(components, operator) components.collect do |component| if component.is_a?(Array) if filter_logical_operator?(component[0]) parse_filter(component) elsif component.size == 2 key, value = component if value.is_a?(Hash) parse_filter(value, key) else construct_component(key, value, operator) end else construct_component(component[0], component[1..-1], operator) end elsif component.is_a?(Symbol) assert_filter_logical_operator(component) nil else parse_filter(component, operator) end end end def construct_component(key, value, operator=nil) value, options = extract_filter_value_options(value) comparison_operator = options[:operator] || "=" if collection?(value) return nil if value.empty? operator, value = normalize_array_filter(value, operator) values = [] value.each do |val| if collection?(val) values.concat(val.collect {|v| [key, comparison_operator, v]}) else values << [key, comparison_operator, val] end end values[0] = values[0][1] if filter_logical_operator?(values[0][1]) parse_filter(values, operator) else [ "(", escape_filter_key(key), comparison_operator, escape_filter_value(value, options), ")" ].join end end def escape_filter_key(key) escape_filter_value(key.to_s) end def escape_filter_value(value, options={}) case value when Numeric, DN value = value.to_s when Time value = Schema::GeneralizedTime.new.normalize_value(value) end value.gsub(/(?:[:()\\\0]|\*\*?)/) do |s| if s == "*" s else s = "*" if s == "**" if s.respond_to?(:getbyte) "\\%02X" % s.getbyte(0) else "\\%02X" % s[0] end end end end def construct_filter(components, operator=nil) operator = normalize_filter_logical_operator(operator) components = components.compact case components.size when 0 nil when 1 filter = components[0] filter = "(!#{filter})" if operator == :not filter else "(#{operator == :and ? '&' : '|'}#{components.join})" end end def collection?(object) !object.is_a?(String) and object.respond_to?(:each) end LOGICAL_OPERATORS = [:and, :or, :not, :&, :|] def filter_logical_operator?(operator) LOGICAL_OPERATORS.include?(operator) end def normalize_filter_logical_operator(operator) assert_filter_logical_operator(operator) case (operator || :and) when :and, :& :and when :or, :| :or else :not end end def assert_filter_logical_operator(operator) return if operator.nil? unless filter_logical_operator?(operator) raise ArgumentError, _("invalid logical operator: %s: available operators: %s") % [operator.inspect, LOGICAL_OPERATORS.inspect] end end # Attempts to reconnect up to the number of times allowed # If forced, try once then fail with ConnectionError if not connected. def reconnect(options={}) options = options.dup force = options[:force] retry_limit = options[:retry_limit] || @retry_limit retry_wait = options[:retry_wait] || @retry_wait options[:reconnect_attempts] ||= 0 loop do @logger.debug {_('Attempting to reconnect')} disconnect! # Reset the attempts if this was forced. options[:reconnect_attempts] = 0 if force options[:reconnect_attempts] += 1 if retry_limit >= 0 begin options[:try_reconnect] = false connect(options) break rescue AuthenticationError, Timeout::Error raise rescue => detail @logger.error do _("Reconnect to server failed: %s: %s\n" \ "Reconnect to server failed backtrace:\n" \ "%s") % [ detail.class, detail.message, detail.backtrace.join("\n"), ] end # Do not loop if forced raise ConnectionError, detail.message if force end unless can_reconnect?(options) raise ConnectionError, _('Giving up trying to reconnect to LDAP server.') end # Sleep before looping sleep retry_wait end true end def reconnect_if_need(options={}) return if connecting? with_timeout(false, options) do reconnect(options) end end # Determine if we have exceed the retry limit or not. # True is reconnecting is allowed - False if not. def can_reconnect?(options={}) retry_limit = options[:retry_limit] || @retry_limit reconnect_attempts = options[:reconnect_attempts] || 0 retry_limit < 0 or reconnect_attempts <= retry_limit end def root_dse_values(key, options={}) dse = root_dse([key], options) return [] if dse.nil? normalized_key = key.downcase dse.each do |_key, _value| return _value if _key.downcase == normalized_key end [] end def root_dse(attrs, options={}) found_attributes = nil if options.has_key?(:try_reconnect) try_reconnect = options[:try_reconnect] else try_reconnect = true end search(:base => "", :scope => :base, :attributes => attrs, :limit => 1, :try_reconnect => try_reconnect, :use_paged_results => false) do |dn, attributes| found_attributes = attributes end found_attributes end def construct_uri(host, port, ssl) protocol = ssl ? "ldaps" : "ldap" URI.parse("#{protocol}://#{host}:#{port}").to_s end def target return nil if @uri.nil? if @with_start_tls "#{@uri}(StartTLS)" else @uri end end def log(name, info=nil) result = nil payload = { :name => name, :info => info || {}, } @instrumenter.instrument("log_info.active_ldap", payload) do result = yield if block_given? end result end def ensure_dn_string(dn) if dn.is_a?(DN) dn.to_s else dn end end end end end activeldap-5.2.4/lib/active_ldap/adapter/net_ldap.rb0000644000004100000410000002431213464071751022454 0ustar www-datawww-datarequire 'digest/md5' require 'active_ldap/adapter/base' module ActiveLdap module Adapter class Base class << self def net_ldap_connection(options) require 'active_ldap/adapter/net_ldap_ext' NetLdap.new(options) end end end class NetLdap < Base METHOD = { :ssl => :simple_tls, :tls => :start_tls, :plain => nil, } def connect(options={}) super do |host, port, method| config = { :host => host, :port => port, } if method config[:encryption] = { :method => method } config[:encryption][:tls_options] = @tls_options if @tls_options end begin uri = construct_uri(host, port, method == :simple_tls) with_start_tls = method == :start_tls info = {:uri => uri, :with_start_tls => with_start_tls} [log("connect", info) {Net::LDAP::Connection.new(config)}, uri, with_start_tls] rescue Net::LDAP::ConnectionError => error raise ConnectionError, error.message rescue Net::LDAP::Error => error message = "#{error.class}: #{error.message}" raise ConnectionError, message, caller(0) + error.backtrace end end end def unbind(options={}) super do log("unbind") do @connection.close # Net::LDAP doesn't implement unbind. end end end def bind(options={}) begin super rescue Net::LDAP::Error raise AuthenticationError, $!.message end end def bind_as_anonymous(options={}) super do execute(:bind, {:name => "bind: anonymous"}, {:method => :anonymous}) true end end def search(options={}) use_paged_results = options[:use_paged_results] if use_paged_results or use_paged_results.nil? paged_results_supported = supported_control.paged_results? else paged_results_supported = false end super(options) do |base, scope, filter, attrs, limit| args = { :base => base, :scope => scope, :filter => filter, :attributes => attrs, :size => limit, :paged_searches_supported => paged_results_supported, } info = { :base => base, :scope => scope_name(scope), :filter => filter, :attributes => attrs, :limit => limit, :paged_results_supported => paged_results_supported, } execute(:search, info, args) do |entry| attributes = {} entry.original_attribute_names.each do |name| value = entry[name] attributes[name] = value if value end yield([entry.dn, attributes]) end end end def delete(targets, options={}) super do |target| args = {:dn => target} info = args.dup execute(:delete, info, args) end end def add(dn, entries, options={}) super do |_dn, _entries| attributes = {} _entries.each do |type, key, attrs| attrs.each do |name, values| attributes[name] = values end end args = {:dn => _dn, :attributes => attributes} info = args.dup execute(:add, info, args) end end def modify(dn, entries, options={}) super do |_dn, _entries| info = {:dn => _dn, :attributes => _entries} execute(:modify, info, :dn => _dn, :operations => parse_entries(_entries)) end end def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={}) super do |_dn, _new_rdn, _delete_old_rdn, _new_superior| info = { :name => "modify: RDN", :dn => _dn, :new_rdn => _new_rdn, :new_superior => _new_superior, :delete_old_rdn => _delete_old_rdn } execute(:rename, info, :olddn => _dn, :newrdn => _new_rdn, :delete_attributes => _delete_old_rdn, :new_superior => _new_superior) end end private def execute(method, info=nil, *args, &block) name = (info || {}).delete(:name) || method result = log(name, info) do begin @connection.send(method, *args, &block) rescue SystemCallError => error message = "#{error.class}: #{error.message}" raise ConnectionError, message, caller(0) + error.backtrace rescue Net::LDAP::ResponseMissingOrInvalidError => error message = "#{error.class}: #{error.message}" message << ": connection may be timed out" raise ConnectionError, message, caller(0) + error.backtrace end end message = nil case result when Hash message = result[:errorMessage] result = result[:resultCode] when Net::LDAP::PDU message = result.error_message result = result.result_code end unless result.zero? klass = LdapError::ERRORS[result] klass ||= LdapError return if klass == LdapError::SizeLimitExceeded message = [Net::LDAP.result2string(result), message].compact.join(": ") raise klass, message end end def ensure_method(method) method ||= "plain" normalized_method = method.to_s.downcase.to_sym return METHOD[normalized_method] if METHOD.has_key?(normalized_method) available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ") format = _("%s is not one of the available connect methods: %s") raise ConfigurationError, format % [method.inspect, available_methods] end def ensure_scope(scope) scope_map = { :base => Net::LDAP::SearchScope_BaseObject, :sub => Net::LDAP::SearchScope_WholeSubtree, :one => Net::LDAP::SearchScope_SingleLevel, } value = scope_map[scope || :sub] if value.nil? available_scopes = scope_map.keys.inspect format = _("%s is not one of the available LDAP scope: %s") raise ArgumentError, format % [scope.inspect, available_scopes] end value end def scope_name(scope) { Net::LDAP::SearchScope_BaseObject => :base, Net::LDAP::SearchScope_WholeSubtree => :sub, Net::LDAP::SearchScope_SingleLevel => :one, }[scope] end def sasl_bind(bind_dn, options={}) super do |_bind_dn, mechanism, quiet| normalized_mechanism = mechanism.downcase.gsub(/-/, '_') sasl_bind_setup = "sasl_bind_setup_#{normalized_mechanism}" next unless respond_to?(sasl_bind_setup, true) initial_credential, challenge_response = send(sasl_bind_setup, _bind_dn, options) args = { :method => :sasl, :initial_credential => initial_credential, :mechanism => mechanism, :challenge_response => challenge_response, } info = { :name => "bind: SASL", :dn => _bind_dn, :mechanism => mechanism, } execute(:bind, info, args) true end end def sasl_bind_setup_digest_md5(bind_dn, options) initial_credential = "" nonce_count = 1 challenge_response = Proc.new do |cred| params = parse_sasl_digest_md5_credential(cred) qops = params["qop"].split(/,/) unless qops.include?("auth") raise ActiveLdap::AuthenticationError, _("unsupported qops: %s") % qops.inspect end qop = "auth" server = @connection.instance_variable_get("@conn").addr[2] realm = params['realm'] uri = "ldap/#{server}" nc = "%08x" % nonce_count nonce = params["nonce"] cnonce = generate_client_nonce requests = { :username => bind_dn.inspect, :realm => realm.inspect, :nonce => nonce.inspect, :cnonce => cnonce.inspect, :nc => nc, :qop => qop, :maxbuf => "65536", "digest-uri" => uri.inspect, } a1 = "#{bind_dn}:#{realm}:#{password(cred, options)}" a1 = "#{Digest::MD5.digest(a1)}:#{nonce}:#{cnonce}" ha1 = Digest::MD5.hexdigest(a1) a2 = "AUTHENTICATE:#{uri}" ha2 = Digest::MD5.hexdigest(a2) response = "#{ha1}:#{nonce}:#{nc}:#{cnonce}:#{qop}:#{ha2}" requests["response"] = Digest::MD5.hexdigest(response) nonce_count += 1 requests.collect do |key, value| "#{key}=#{value}" end.join(",") end [initial_credential, challenge_response] end def parse_sasl_digest_md5_credential(cred) params = {} cred.scan(/(\w+)=(\"?)(.+?)\2(?:,|$)/) do |name, sep, value| params[name] = value end params end CHARS = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a def generate_client_nonce(size=32) nonce = "" size.times do |i| nonce << CHARS[rand(CHARS.size)] end nonce end def simple_bind(bind_dn, options={}) super do |_bind_dn, password| args = { :method => :simple, :username => _bind_dn, :password => password, } execute(:bind, {:dn => _bind_dn}, args) true end end def parse_entries(entries) result = [] entries.each do |type, key, attributes| mod_type = ensure_mod_type(type) attributes.each do |name, values| result << [mod_type, name, values] end end result end def ensure_mod_type(type) case type when :replace, :add, :delete type else raise ArgumentError, _("unknown type: %s") % type end end end end end activeldap-5.2.4/lib/active_ldap/adapter/jndi.rb0000644000004100000410000001337113464071751021615 0ustar www-datawww-datarequire 'active_ldap/adapter/base' module ActiveLdap module Adapter class Base class << self def jndi_connection(options) require 'active_ldap/adapter/jndi_connection' Jndi.new(options) end end end class Jndi < Base METHOD = { :ssl => :ssl, :tls => :start_tls, :plain => nil, } def connect(options={}) super do |host, port, method| uri = construct_uri(host, port, method == :ssl) with_start_tls = method == :start_tls info = {:uri => uri, :with_start_tls => with_start_tls} [log("connect", info) {JndiConnection.new(host, port, method, @timeout)}, uri, with_start_tls] end end def connecting? super and @connection.bound? end def unbind(options={}) super do execute(:unbind) end end def bind_as_anonymous(options={}) super do execute(:bind_as_anonymous, :name => "bind: anonymous") true end end def search(options={}, &block) super(options) do |base, scope, filter, attrs, limit| info = { :base => base, :scope => scope_name(scope), :filter => filter, :attributes => attrs, :limit => limit, } execute(:search, info, base, scope, filter, attrs, limit, &block) end end def delete(targets, options={}) super do |target| execute(:delete, {:dn => target}, target) end end def add(dn, entries, options={}) super do |_dn, _entries| info = {:dn => _dn, :attributes => _entries} execute(:add, info, _dn, parse_entries(_entries)) end end def modify(dn, entries, options={}) super do |_dn, _entries| info = {:dn => _dn, :attributes => _entries} execute(:modify, info, _dn, parse_entries(_entries)) end end def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={}) super do |_dn, _new_rdn, _delete_old_rdn, _new_superior| info = { :name => "modify: RDN", :dn => _dn, :new_rdn => _new_rdn, :new_superior => _new_superior, :delete_old_rdn => _delete_old_rdn } _new_rdn = "#{_new_rdn},#{_new_superior}" if _new_superior execute(:modify_rdn, info, _dn, _new_rdn, _delete_old_rdn) end end private def execute(method, info=nil, *args, &block) name = (info || {}).delete(:name) || method log(name, info) {@connection.send(method, *args, &block)} rescue JndiConnection::CommunicationException, JndiConnection::ServiceUnavailableException => e disconnect! if connecting? raise ActiveLdap::ConnectionError.new(e.getMessage()) rescue JndiConnection::NamingException if /\[LDAP: error code (\d+) - ([^\]]+)\]/ =~ $!.to_s message = $2 klass = LdapError::ERRORS[Integer($1)] klass ||= ActiveLdap::LdapError raise klass, message elsif /LDAP response read timed out/ =~ $!.to_s disconnect! if connecting? raise Timeout::Error.new($!.to_s) end raise end def ensure_method(method) method ||= "plain" normalized_method = method.to_s.downcase.to_sym return METHOD[normalized_method] if METHOD.has_key?(normalized_method) available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ") format = _("%s is not one of the available connect methods: %s") raise ConfigurationError, format % [method.inspect, available_methods] end def ensure_scope(scope) scope_map = { :base => JndiConnection::Scope::OBJECT, :one => JndiConnection::Scope::ONE_LEVEL, :sub => JndiConnection::Scope::SUBTREE, } value = scope_map[scope || :sub] if value.nil? available_scopes = scope_map.keys.inspect format = _("%s is not one of the available LDAP scope: %s") raise ArgumentError, format % [scope.inspect, available_scopes] end value end def scope_name(scope) { JndiConnection::Scope::OBJECT => :base, JndiConnection::Scope::ONE_LEVEL => :one, JndiConnection::Scope::SUBTREE => :sub, }[scope] end def sasl_bind(bind_dn, options={}) super do |_bind_dn, mechanism, quiet| info = { :name => "bind: SASL", :dn => _bind_dn, :mechanism => mechanism } execute(:sasl_bind, info, _bind_dn, mechanism, quiet) true end end def simple_bind(bind_dn, options={}) super do |_bind_dn, password| info = {:name => "bind", :dn => _bind_dn} execute(:simple_bind, info, _bind_dn, password) true end end def parse_entries(entries) result = [] entries.each do |type, key, attributes| mod_type = ensure_mod_type(type) binary = schema.attribute(key).binary? attributes.each do |name, values| real_binary = binary if values.any? {|value| Ldif::Attribute.binary_value?(value)} real_binary = true end result << JndiConnection::ModifyRecord.new(mod_type, name, values, real_binary) end end result end def ensure_mod_type(type) case type when :replace, :add type when :delete :remove else raise ArgumentError, _("unknown type: %s") % type end end end end end activeldap-5.2.4/lib/active_ldap/adapter/net_ldap_ext.rb0000644000004100000410000000106713464071751023336 0ustar www-datawww-datarequire 'net/ldap' module Net class LDAP class Entry alias initialize_without_original_attribute_names initialize def initialize(*args) @original_attribute_names = [] initialize_without_original_attribute_names(*args) end alias aset_without_original_attribute_names []= def []=(name, value) @original_attribute_names << name aset_without_original_attribute_names(name, value) end def original_attribute_names @original_attribute_names.compact.uniq end end end end activeldap-5.2.4/lib/active_ldap/adapter/ldap.rb0000644000004100000410000002441313464071751021610 0ustar www-datawww-datarequire 'active_ldap/adapter/base' module ActiveLdap module Adapter class Base class << self def ldap_connection(options) require 'active_ldap/adapter/ldap_ext' Ldap.new(options) end end end class Ldap < Base module Method class Base def ssl? false end def start_tls? false end end class SSL < Base def connect(host, port, options={}) LDAP::SSLConn.new(host, port, false) end def ssl? true end end class TLS < Base def connect(host, port, options={}) connection = LDAP::Conn.new(host, port) if connection.get_option(LDAP::LDAP_OPT_PROTOCOL_VERSION) < 3 connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3) end tls_options = options[:tls_options] if tls_options and LDAP.const_defined?(:LDAP_OPT_X_TLS_NEWCTX) tls_options.each do |key, value| case key when :verify_mode case value when :none, OpenSSL::SSL::SSL_VERIFY_NONE connection.set_option(LDAP::LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP::LDAP_OPT_X_TLS_NEVER) when :peer, OpenSSL::SSL::SSL_VERIFY_PEER connection.set_option(LDAP::LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP::LDAP_OPT_X_TLS_DEMAND) end when :verify_hostname unless value connection.set_option(LDAP::LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP::LDAP_OPT_X_TLS_ALLOW) end end end connection.set_option(LDAP::LDAP_OPT_X_TLS_NEWCTX, 0) end connection.start_tls connection end def start_tls? true end end class Plain < Base def connect(host, port, options={}) LDAP::Conn.new(host, port) end end end def connect(options={}) super do |host, port, method| uri = construct_uri(host, port, method.ssl?) with_start_tls = method.start_tls? info = { :uri => uri, :with_start_tls => with_start_tls, :tls_options => @tls_options, } connection = log("connect", info) do method.connect(host, port, :tls_options => @tls_options) end [connection, uri, with_start_tls] end end def unbind(options={}) super do execute(:unbind) end end def bind(options={}) super do @connection.error_message end end def bind_as_anonymous(options={}) super do execute(:bind, :name => "bind: anonymous") true end end def search(options={}) super(options) do |base, scope, filter, attrs, limit| begin use_paged_results = options[:use_paged_results] if use_paged_results or use_paged_results.nil? use_paged_results = supported_control.paged_results? end info = { :base => base, :scope => scope_name(scope), :filter => filter, :attributes => attrs, :limit => limit, } options = { :base => base, :scope => scope, :filter => filter, :attributes => attrs, :limit => limit, :use_paged_results => use_paged_results } execute(:search_full, info, options) do |entry| attributes = {} entry.attrs.each do |attr| value = entry.vals(attr) attributes[attr] = value if value end yield([entry.dn, attributes]) end rescue RuntimeError if $!.message == "no result returned by search" @logger.debug do args = [filter, attrs.inspect] _("No matches: filter: %s: attributes: %s") % args end else raise end end end end def delete(targets, options={}) super do |target| controls = options[:controls] info = {:dn => target} if controls info.merge!(:name => :delete, :controls => controls) execute(:delete_ext, info, target, controls, []) else execute(:delete, info, target) end end end def add(dn, entries, options={}) super do |_dn, _entries| controls = options[:controls] attributes = parse_entries(_entries) info = {:dn => _dn, :attributes => _entries} if controls info.merge!(:name => :add, :controls => controls) execute(:add_ext, info, _dn, attributes, controls, []) else execute(:add, info, _dn, attributes) end end end def modify(dn, entries, options={}) super do |_dn, _entries| controls = options[:controls] attributes = parse_entries(_entries) info = {:dn => _dn, :attributes => _entries} if controls info.merge!(:name => :modify, :controls => controls) execute(:modify_ext, info, _dn, attributes, controls, []) else execute(:modify, info, _dn, attributes) end end end def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={}) super do |_dn, _new_rdn, _delete_old_rdn, _new_superior| rename_available_p = @connection.respond_to?(:rename) if _new_superior and not rename_available_p raise NotImplemented.new(_("modify RDN with new superior")) end info = { :name => "modify: RDN", :dn => _dn, :new_rdn => _new_rdn, :new_superior => _new_superior, :delete_old_rdn => _delete_old_rdn } if rename_available_p execute(:rename, info, _dn, _new_rdn, _new_superior, _delete_old_rdn, [], []) else execute(:modrdn, info, _dn, _new_rdn, _delete_old_rdn) end end end private def prepare_connection(options={}) operation(options) do @connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3) unless follow_referrals?(options) @connection.set_option(LDAP::LDAP_OPT_REFERRALS, 0) end end end def execute(method, info=nil, *args, &block) begin name = (info || {}).delete(:name) || method log(name, info) {@connection.send(method, *args, &block)} rescue LDAP::ResultError @connection.assert_error_code raise $!.message end end def ensure_method(method) normalized_method = method.to_s.downcase Method.constants.each do |name| if normalized_method == name.to_s.downcase return Method.const_get(name).new end end available_methods = Method.constants.collect do |name| name.downcase.to_sym.inspect end.join(", ") format = _("%s is not one of the available connect methods: %s") raise ConfigurationError, format % [method.inspect, available_methods] end def ensure_scope(scope) scope_map = { :base => LDAP::LDAP_SCOPE_BASE, :sub => LDAP::LDAP_SCOPE_SUBTREE, :one => LDAP::LDAP_SCOPE_ONELEVEL, } value = scope_map[scope || :sub] if value.nil? available_scopes = scope_map.keys.inspect format = _("%s is not one of the available LDAP scope: %s") raise ArgumentError, format % [scope.inspect, available_scopes] end value end def scope_name(scope) { LDAP::LDAP_SCOPE_BASE => :base, LDAP::LDAP_SCOPE_SUBTREE => :sub, LDAP::LDAP_SCOPE_ONELEVEL => :one, }[scope] end def sasl_bind(bind_dn, options={}) super do |_bind_dn, mechanism, quiet| begin _bind_dn ||= '' sasl_quiet = @connection.sasl_quiet @connection.sasl_quiet = quiet unless quiet.nil? args = [_bind_dn, mechanism] credential = nil if need_credential_sasl_mechanism?(mechanism) credential = password(_bind_dn, options) end if @sasl_options credential ||= "" args.concat([credential, nil, nil, @sasl_options]) else args << credential if credential end info = { :name => "bind: SASL", :dn => _bind_dn, :mechanism => mechanism } execute(:sasl_bind, info, *args) true ensure @connection.sasl_quiet = sasl_quiet end end end def simple_bind(bind_dn, options={}) super do |_bind_dn, password| execute(:bind, {:dn => _bind_dn}, _bind_dn, password) true end end def parse_entries(entries) result = [] entries.each do |type, key, attributes| mod_type = ensure_mod_type(type) binary = schema.attribute(key).binary? mod_type |= LDAP::LDAP_MOD_BVALUES if binary attributes.each do |name, values| additional_mod_type = 0 if values.any? {|value| Ldif::Attribute.binary_value?(value)} additional_mod_type |= LDAP::LDAP_MOD_BVALUES end result << LDAP.mod(mod_type | additional_mod_type, name, values) end end result end def ensure_mod_type(type) case type when :replace, :add, :delete LDAP.const_get("LDAP_MOD_#{type.to_s.upcase}") else raise ArgumentError, _("unknown type: %s") % type end end end end end activeldap-5.2.4/lib/active_ldap/ldif.rb0000644000004100000410000006032513464071751020170 0ustar www-datawww-datarequire "strscan" require "uri" require "open-uri" module ActiveLdap class Ldif module Attributes module_function def encode(attributes) return "" if attributes.empty? result = "" normalize(attributes).sort_by {|name,| name}.each do |name, values| values.each do |options, value| result << Attribute.encode([name, *options].join(";"), value) end end result end def normalize(attributes) result = {} attributes.each do |name, values| result[name] = Attribute.normalize_value(values).sort end result end end module Attribute SIZE = 75 module_function def binary_value?(value) if value.respond_to?(:encoding) return true if value.encoding == Encoding.find("ascii-8bit") end if /\A#{Parser::SAFE_STRING}\z/ =~ value false else true end end def encode(name, value) return "#{name}:\n" if value.blank? result = "#{name}:" value = value.to_s unless value.is_a?(String) if value[-1, 1] == ' ' or binary_value?(value) result << ":" value = [value].pack("m").gsub(/\n/, '') end result << " " first_line_value_size = SIZE - result.size if value.size > first_line_value_size first_line_value = value[0, first_line_value_size] rest_value = value[first_line_value_size..-1] else first_line_value = value rest_value = nil end result << "#{first_line_value}\n" return result if rest_value.nil? rest_value.scan(/.{1,#{SIZE - 1}}/).each do |line| # FIXME result << " #{line}\n" end result end def normalize_value(value, result=[]) case value when Array value.each {|val| normalize_value(val, result)} when Hash value.each do |option, val| normalize_value(val).each do |options, v| result << [[option] + options, v] end end result else result << [[], value] end result end end class Parser include GetTextSupport attr_reader :ldif def initialize(source) @ldif = nil source = source.to_s if source.is_a?(LDIF) @source = source end ATTRIBUTE_TYPE_CHARS = /[a-zA-Z][a-zA-Z0-9\-]*/ SAFE_CHAR = /[\x01-\x09\x0B-\x0C\x0E-\x7F]/ SAFE_INIT_CHAR = /[\x01-\x09\x0B-\x0C\x0E-\x1F\x21-\x39\x3B\x3D-\x7F]/ SAFE_STRING = /#{SAFE_INIT_CHAR}#{SAFE_CHAR}*/ FILL = / */ def parse return @ldif if @ldif @scanner = Scanner.new(@source) raise version_spec_is_missing unless @scanner.scan(/version:/) @scanner.scan(FILL) version = @scanner.scan(/\d+/) raise version_number_is_missing if version.nil? version = Integer(version) raise unsupported_version(version) if version != 1 raise separator_is_missing unless @scanner.scan_separators records = parse_records @ldif = LDIF.new(records) end private def read_base64_value value = @scanner.scan(/[a-zA-Z0-9\+\/=]+/) return nil if value.nil? encoding = value.encoding if value.respond_to?(:encoding) value = value.unpack("m")[0].chomp if value.respond_to?(:force_encoding) value.force_encoding(encoding) value.force_encoding("ascii-8bit") unless value.valid_encoding? end value end def read_external_file uri_string = @scanner.scan(URI::ABS_URI) raise uri_is_missing if uri_string.nil? uri_string.chomp! uri = nil begin uri = URI.parse(uri_string) rescue URI::Error raise invalid_uri(uri_string, $!.message) end if uri.scheme == "file" File.open(uri.path, "rb") {|file| file.read} else uri.read end end def parse_dn(dn_string) DN.parse(dn_string).to_s rescue DistinguishedNameInvalid raise invalid_dn(dn_string, $!.reason) end def parse_attributes(least=0, &block) i = 0 attributes = {} block ||= Proc.new {@scanner.check_separator} loop do i += 1 if i >= least break if block.call or @scanner.eos? end type, options, value = parse_attribute if @scanner.scan_separator.nil? and !@scanner.eos? raise separator_is_missing end attributes[type] ||= [] container = attributes[type] options.each do |option| parent = container.find do |val| val.is_a?(Hash) and val.has_key?(option) end if parent.nil? parent = {option => []} container << parent end container = parent[option] end container << value end raise attribute_spec_is_missing if attributes.size < least attributes end def parse_attribute_description type = @scanner.scan(ATTRIBUTE_TYPE_CHARS) raise attribute_type_is_missing if type.nil? options = parse_options [type, options] end def parse_attribute type, options = parse_attribute_description value = parse_attribute_value [type, options, value] end def parse_options options = [] while @scanner.scan(/;/) option = @scanner.scan(ATTRIBUTE_TYPE_CHARS) raise option_is_missing if option.nil? options << option end options end def parse_attribute_value(accept_external_file=true) raise attribute_value_separator_is_missing if @scanner.scan(/:/).nil? if @scanner.scan(/:/) @scanner.scan(FILL) read_base64_value elsif accept_external_file and @scanner.scan(/ dn}) end def to_s result = to_s_prelude result << to_s_content result end def ==(other) other.is_a?(self.class) and @dn == other.dn and Attributes.normalize(@attributes) == Attributes.normalize(other.attributes) end private def to_s_prelude Attribute.encode("dn", dn) end def to_s_content Attributes.encode(@attributes) end end class ContentRecord < Record end class ChangeRecord < Record attr_reader :controls, :change_type def initialize(dn, attributes, controls, change_type) super(dn, attributes) @controls = controls @change_type = change_type end def add? @change_type == "add" end def delete? @change_type == "delete" end def modify? @change_type == "modify" end def modify_dn? @change_type == "moddn" end def modify_rdn? @change_type == "modrdn" end def ==(other) super(other) and @controls = other.controls and @change_type == other.change_type end private def to_s_prelude result = super @controls.each do |control| result << control.to_s end result end def to_s_content result = "changetype: #{@change_type}\n" result << super result end class Control attr_reader :type, :value def initialize(type, criticality, value) @type = type @criticality = normalize_criticality(criticality) @value = value end def criticality? @criticality end def to_a [@type, @criticality, @value] end def to_hash { :type => @type, :criticality => @criticality, :value => @value, } end def to_s result = "control: #{@type}" result << " #{@criticality}" unless @criticality.nil? result << @value if @value result << "\n" result end def ==(other) other.is_a?(self.class) and @type == other.type and @criticality = other.criticality and @value == other.value end private def normalize_criticality(criticality) case criticality when "true", true true when "false", false false when nil nil else raise ArgumentError, _("invalid criticality value: %s") % criticality.inspect end end end end class AddRecord < ChangeRecord def initialize(dn, controls=[], attributes={}) super(dn, attributes, controls, "add") end end class DeleteRecord < ChangeRecord def initialize(dn, controls=[]) super(dn, {}, controls, "delete") end end class ModifyNameRecord < ChangeRecord attr_reader :new_rdn, :new_superior def initialize(dn, controls, change_type, new_rdn, delete_old_rdn, new_superior) super(dn, {}, controls, change_type) @new_rdn = new_rdn @delete_old_rdn = normalize_delete_old_rdn(delete_old_rdn) @new_superior = new_superior end def delete_old_rdn? @delete_old_rdn end private def normalize_delete_old_rdn(delete_old_rdn) case delete_old_rdn when "1", true true when "0", false false when nil nil else raise ArgumentError, _("invalid deleteoldrdn value: %s") % delete_old_rdn.inspect end end def to_s_content result = super result << "newrdn: #{@new_rdn}\n" result << "deleteoldrdn: #{@delete_old_rdn ? 1 : 0}\n" result << Attribute.encode("newsuperior", @new_superior) if @new_superior result end end class ModifyDNRecord < ModifyNameRecord def initialize(dn, controls, new_rdn, delete_old_rdn, new_superior=nil) super(dn, controls, "moddn", new_rdn, delete_old_rdn, new_superior) end end class ModifyRDNRecord < ModifyNameRecord def initialize(dn, controls, new_rdn, delete_old_rdn, new_superior=nil) super(dn, controls, "modrdn", new_rdn, delete_old_rdn, new_superior) end end class ModifyRecord < ChangeRecord include Enumerable attr_reader :operations def initialize(dn, controls=[], operations=[]) super(dn, {}, controls, "modify") @operations = operations end def each(&block) @operations.each(&block) end def <<(operation) @operations << operation end def add_operation(type, attribute, options, attributes) klass = self.class.const_get("#{type.to_s.capitalize}Operation") self << klass.new(attribute, options, attributes) end def ==(other) super(other) and @operations == other.operations end private def to_s_content result = super return result if @operations.empty? @operations.collect do |operation| result << "#{operation}-\n" end result end class Operation attr_reader :type, :attribute, :options, :attributes def initialize(type, attribute, options, attributes) @type = type @attribute = attribute @options = options @attributes = attributes end def full_attribute_name [@attribute, *@options].join(";") end def add? @type == "add" end def delete? @type == "delete" end def replace? @type == "replace" end def to_s Attribute.encode(@type, full_attribute_name) + Attributes.encode(@attributes) end def ==(other) other.is_a?(self.class) and @type == other.type and full_attribute_name == other.full_attribute_name and Attributes.normalize(@attributes) == Attributes.normalize(other.attributes) end end class AddOperation < Operation def initialize(attribute, options, attributes) super("add", attribute, options, attributes) end end class DeleteOperation < Operation def initialize(attribute, options, attributes) super("delete", attribute, options, attributes) end end class ReplaceOperation < Operation def initialize(attribute, options, attributes) super("replace", attribute, options, attributes) end end end end LDIF = Ldif end activeldap-5.2.4/lib/active_ldap/association/0000755000004100000410000000000013464071751021233 5ustar www-datawww-dataactiveldap-5.2.4/lib/active_ldap/association/proxy.rb0000644000004100000410000000430513464071751022743 0ustar www-datawww-datamodule ActiveLdap module Association class Proxy alias_method :proxy_respond_to?, :respond_to? alias_method :proxy_extend, :extend delegate :to_param, :to => :target def initialize(owner, options) @owner = owner @options = options reset extend(options[:extend]) if options[:extend] end def respond_to?(symbol, include_priv=false) proxy_respond_to?(symbol, include_priv) or (load_target && @target.respond_to?(symbol, include_priv)) end def ===(other) load_target and other === @target end def reset @target = nil @loaded = false end def reload reset load_target end def loaded? @loaded end def loaded @loaded = true end def target @target end def target=(target) @target = target loaded end def exists? load_target not @target.nil? end private def method_missing(method, *args, &block) load_target @target.send(method, *args, &block) end def foreign_class klass = @owner.class.associated_class(@options[:association_id]) klass = @owner.class.module_eval(klass) if klass.is_a?(String) klass end def have_foreign_key? false end def primary_key @options[:primary_key_name] || @owner.dn_attribute end def foreign_key @options[:foreign_key_name] || foreign_class.dn_attribute end def load_target if !@owner.new_entry? or have_foreign_key? begin @target = find_target unless loaded? rescue EntryNotFound reset end end loaded if target target end def find_options(options={}) if @owner.connection != @owner.class.connection {:connection => @owner.connection}.merge(options) else options end end def infect_connection(target) conn = @owner.instance_variable_get("@connection") target.connection = conn if conn end end end end activeldap-5.2.4/lib/active_ldap/association/has_many_wrap.rb0000644000004100000410000000421513464071751024412 0ustar www-datawww-datarequire 'active_ldap/association/collection' require 'active_ldap/association/has_many_utils' module ActiveLdap module Association class HasManyWrap < Collection include HasManyUtils private def insert_entry(entry) old_value = @owner[@options[:wrap], true] _foreign_key = foreign_key if _foreign_key == "dn" old_value = dn_values_to_string_values(old_value) end current_value = entry[_foreign_key, true] current_value = dn_values_to_string_values(current_value) new_value = (old_value + current_value).uniq.sort if old_value != new_value @owner[@options[:wrap]] = new_value @owner.save unless @owner.new_entry? end end def delete_entries(entries) old_value = @owner[@options[:wrap], true] _foreign_key = foreign_key if _foreign_key == "dn" old_value = dn_values_to_string_values(old_value) end current_value = entries.collect {|entry| entry[_foreign_key]} current_value = dn_values_to_string_values(current_value) new_value = old_value - current_value new_value = new_value.uniq.sort if old_value != new_value @owner[@options[:wrap]] = new_value @owner.save unless @owner.new_entry? end end def find_target targets, requested_targets = collect_targets(@options[:wrap], true) return [] if targets.nil? found_targets = {} _foreign_key = foreign_key targets.each do |target| found_targets[target[_foreign_key]] ||= target end klass = foreign_class requested_targets.collect do |name| found_targets[name] || klass.new(name) end end def foreign_key @options[:primary_key_name] || foreign_class.dn_attribute end def add_entries(*entries) result = true load_target flatten_deeper(entries).each do |entry| infect_connection(entry) insert_entry(entry) or result = false @target << entry end result && self end end end end activeldap-5.2.4/lib/active_ldap/association/children.rb0000644000004100000410000000066413464071751023356 0ustar www-datawww-datarequire 'active_ldap/association/collection' module ActiveLdap module Association class Children < Collection private def insert_entry(entry) entry.dn = [entry.id, @owner.dn.to_s].join(",") entry.save end def find_target @owner.find(:all, :base => @owner.dn, :scope => :one) end def delete_entries(entries) entries.each(&:destroy) end end end end activeldap-5.2.4/lib/active_ldap/association/belongs_to.rb0000644000004100000410000000222213464071751023711 0ustar www-datawww-datarequire 'active_ldap/association/proxy' module ActiveLdap module Association class BelongsTo < Proxy def replace(entry) if entry.nil? @target = @owner[@options[:foreign_key_name]] = nil else @target = (Proxy === entry ? entry.target : entry) infect_connection(@target) unless entry.new_entry? @owner[@options[:foreign_key_name]] = entry[primary_key] end @updated = true end loaded entry end def updated? @updated end private def have_foreign_key? not @owner[@options[:foreign_key_name]].nil? end def find_target value = @owner[@options[:foreign_key_name]] raise EntryNotFound if value.nil? key = primary_key if key == "dn" result = foreign_class.find(value, find_options) else filter = {key => value} options = find_options(:filter => filter, :limit => 1) result = foreign_class.find(:all, options).first end raise EntryNotFound if result.nil? result end end end end activeldap-5.2.4/lib/active_ldap/association/has_many_utils.rb0000644000004100000410000000235213464071751024601 0ustar www-datawww-datamodule ActiveLdap module Association module HasManyUtils private def collect_targets(requested_target_key, need_requested_targets=false) _foreign_key = foreign_key return [] if _foreign_key.nil? requested_targets = @owner[requested_target_key, true] requested_targets = requested_targets.reject(&:nil?) if requested_targets.empty? targets = [] elsif _foreign_key == "dn" requested_targets = requested_targets.collect do |target| if target.is_a?(DN) target else DN.parse(target) end end targets = [] requested_targets.each do |target| begin targets << foreign_class.find(target, find_options) rescue EntryNotFound end end else components = requested_targets.collect do |value| [_foreign_key, value] end options = find_options(:filter => [:or, *components]) targets = foreign_class.find(:all, options) end if need_requested_targets [targets, requested_targets] else targets end end end end end activeldap-5.2.4/lib/active_ldap/association/has_many.rb0000644000004100000410000000144413464071751023362 0ustar www-datawww-datarequire 'active_ldap/association/collection' require 'active_ldap/association/has_many_utils' module ActiveLdap module Association class HasMany < Collection include HasManyUtils private def insert_entry(entry) entry[foreign_key] = @owner[primary_key] entry.save end def find_target collect_targets(primary_key) end def delete_entries(entries) _foreign_key = foreign_key components = @owner[primary_key, true].reject do |value| value.nil? end filter = [:and, [:and, {_foreign_key => components}], [:or, {foreign_class.dn_attribute => entries.collect(&:id)}]] foreign_class.update_all({_foreign_key => []}, filter) end end end end activeldap-5.2.4/lib/active_ldap/association/belongs_to_many.rb0000644000004100000410000000374113464071751024744 0ustar www-datawww-datarequire 'active_ldap/association/collection' module ActiveLdap module Association class BelongsToMany < Collection private def normalize_entry(entry) _foreign_class = foreign_class entry = _foreign_class.find(entry) unless entry.is_a?(_foreign_class) entry end def insert_entry(entry) old_value = entry[@options[:many], true] primary_key_name = @options[:primary_key_name] if primary_key_name == "dn" old_value = dn_values_to_string_values(old_value) end current_value = @owner[primary_key_name, true] current_value = dn_values_to_string_values(current_value) new_value = old_value + current_value new_value = new_value.uniq.sort if old_value != new_value entry[@options[:many]] = new_value entry.save end end def delete_entries(entries) _foreign_class = foreign_class entries.each do |entry| entry = _foreign_class.find(entry) unless entry.is_a?(_foreign_class) old_value = entry[@options[:many], true] primary_key_name = @options[:primary_key_name] if primary_key_name == "dn" old_value = dn_values_to_string_values(old_value) end current_value = @owner[primary_key_name, true] current_value = dn_values_to_string_values(current_value) new_value = old_value - current_value new_value = new_value.uniq.sort if old_value != new_value entry[@options[:many]] = new_value entry.save end end end def find_target values = @owner[@options[:primary_key_name], true].compact return [] if values.empty? key = @options[:many] components = values.collect do |value| [key, value] end options = find_options(:filter => [:or, *components]) foreign_class.find(:all, options) end end end end activeldap-5.2.4/lib/active_ldap/association/collection.rb0000644000004100000410000000450513464071751023717 0ustar www-datawww-datarequire 'active_ldap/association/proxy' module ActiveLdap module Association class Collection < Proxy include Enumerable def to_ary load_target @target.to_ary end def reset @target = [] @loaded = false end def <<(*entries) add_entries(*entries) end alias_method(:push, :<<) alias_method(:concat, :<<) def each(&block) to_ary.each(&block) end def delete(*entries) entries = flatten_deeper(entries).reject do |entry| @target.delete(entry) if entry.new_entry? entry.new_entry? end return if entries.empty? delete_entries(entries) entries.each do |entry| @target.delete(entry) end end def replace(others) load_target entry = @target.first if entry.nil? deleted_entries = [] added_entries = others else base_class = entry.class others = others.collect do |other| other = base_class.find(other) unless other.is_a?(base_class) other end deleted_entries = @target - others added_entries = others - @target end delete(deleted_entries) concat(added_entries) end def exists? load_target not @target.empty? end private def flatten_deeper(array) array.collect do |element| element.respond_to?(:flatten) ? element.flatten : element end.flatten end def normalize_entry(entry) entry end def insert_entry(entry) entry[@options[:foreign_key_name]] = @owner[@options[:local_key_name]] entry.save end def add_entries(*entries) result = true load_target flatten_deeper(entries).each do |entry| entry = normalize_entry(entry) unless @owner.new_entry? infect_connection(entry) result &&= insert_entry(entry) end @target << entry end result && self end def dn_values_to_string_values(values) values.collect do |value| if value.is_a?(DN) value.to_s else value end end end end end end activeldap-5.2.4/lib/active_ldap/ldap_error.rb0000644000004100000410000000377713464071751021413 0ustar www-datawww-datamodule ActiveLdap class LdapError < Error class << self def define(code, name, target) klass_name = name.downcase.camelize target.module_eval(<<-EOC, __FILE__, __LINE__ + 1) class #{klass_name} < #{self} CODE = #{code} def code CODE end end EOC target.const_get(klass_name) end end ERRORS = {} { 0x00 => "SUCCESS", 0x01 => "OPERATIONS_ERROR", 0x02 => "PROTOCOL_ERROR", 0x03 => "TIME_LIMIT_EXCEEDED", 0x04 => "SIZE_LIMIT_EXCEEDED", 0x05 => "COMPARE_FALSE", 0x06 => "COMPARE_TRUE", 0x07 => "AUTH_METHOD_NOT_SUPPORTED", 0x08 => "STRONG_AUTH_REQUIRED", 0x09 => "PARTIAL_RESULTS", # LDAPv2+ (not LDAPv3) 0x0a => "REFERRAL", 0x0b => "ADMIN_LIMIT_EXCEEDED", 0x0c => "UNAVAILABLE_CRITICAL_EXTENSION", 0x0d => "CONFIDENTIALITY_REQUIRED", 0x0e => "LDAP_SASL_BIND_IN_PROGRESS", 0x10 => "NO_SUCH_ATTRIBUTE", 0x11 => "UNDEFINED_TYPE", 0x12 => "INAPPROPRIATE_MATCHING", 0x13 => "CONSTRAINT_VIOLATION", 0x14 => "TYPE_OR_VALUE_EXISTS", 0x15 => "INVALID_SYNTAX", 0x20 => "NO_SUCH_OBJECT", 0x21 => "ALIAS_PROBLEM", 0x22 => "INVALID_DN_SYNTAX", 0x23 => "IS_LEAF", 0x24 => "ALIAS_DEREF_PROBLEM", 0x2F => "PROXY_AUTHZ_FAILURE", 0x30 => "INAPPROPRIATE_AUTH", 0x31 => "INVALID_CREDENTIALS", 0x32 => "INSUFFICIENT_ACCESS", 0x33 => "BUSY", 0x34 => "UNAVAILABLE", 0x35 => "UNWILLING_TO_PERFORM", 0x36 => "LOOP_DETECT", 0x40 => "NAMING_VIOLATION", 0x41 => "OBJECT_CLASS_VIOLATION", 0x42 => "NOT_ALLOWED_ON_NONLEAF", 0x43 => "NOT_ALLOWED_ON_RDN", 0x44 => "ALREADY_EXISTS", 0x45 => "NO_OBJECT_CLASS_MODS", 0x46 => "RESULTS_TOO_LARGE", 0x47 => "AFFECTS_MULTIPLE_DSAS", 0x50 => "OTHER", }.each do |code, name| ERRORS[code] = LdapError.define(code, name, self) end end end activeldap-5.2.4/lib/active_ldap/human_readable.rb0000644000004100000410000001021013464071751022165 0ustar www-datawww-datamodule ActiveLdap module HumanReadable def self.included(base) super base.extend(ClassMethods) end module ClassMethods def human_attribute_name(attribute_or_name, options={}) logger.warn("options was ignored.") unless options.empty? msgid = human_attribute_name_msgid(attribute_or_name) msgid ||= human_attribute_name_with_gettext(attribute_or_name) s_(msgid) end def human_attribute_name_msgid(attribute_or_name) if attribute_or_name.is_a?(Schema::Attribute) name = attribute_or_name.name else attribute = schema.attribute(attribute_or_name.to_s) return nil if attribute.id.nil? if attribute.name == attribute_or_name or attribute.aliases.include?(attribute_or_name.to_s) name = attribute_or_name else return nil end end "LDAP|Attribute|#{name}" end def human_attribute_description(attribute_or_name) msgid = human_attribute_description_msgid(attribute_or_name) return nil if msgid.nil? s_(msgid) end def human_attribute_description_msgid(attribute_or_name) if attribute_or_name.is_a?(Schema::Attribute) attribute = attribute_or_name else attribute = schema.attribute(attribute_or_name.to_s) return nil if attribute.nil? end description = attribute.description return nil if description.nil? "LDAP|Description|Attribute|#{attribute.name}|#{description}" end def human_object_class_name(object_class_or_name) s_(human_object_class_name_msgid(object_class_or_name)) end def human_object_class_name_msgid(object_class_or_name) if object_class_or_name.is_a?(Schema::ObjectClass) name = object_class_or_name.name else name = object_class_or_name end "LDAP|ObjectClass|#{name}" end def human_object_class_description(object_class_or_name) msgid = human_object_class_description_msgid(object_class_or_name) return nil if msgid.nil? s_(msgid) end def human_object_class_description_msgid(object_class_or_name) if object_class_or_name.is_a?(Schema::ObjectClass) object_class = object_class_or_name else object_class = schema.object_class(object_class_or_name) return nil if object_class.nil? end description = object_class.description return nil if description.nil? "LDAP|Description|ObjectClass|#{object_class.name}|#{description}" end def human_syntax_name(syntax_or_id) s_(human_syntax_name_msgid(syntax_or_id)) end def human_syntax_name_msgid(syntax_or_id) if syntax_or_id.is_a?(Schema::Syntax) id = syntax_or_id.id else id = syntax_or_id end "LDAP|Syntax|#{id}" end def human_syntax_description(syntax_or_id) msgid = human_syntax_description_msgid(syntax_or_id) return nil if msgid.nil? s_(msgid) end def human_syntax_description_msgid(syntax_or_id) if syntax_or_id.is_a?(Schema::Syntax) syntax = syntax_or_id else syntax = schema.ldap_syntax(syntax_or_id) return nil if syntax.nil? end description = syntax.description return nil if description.nil? "LDAP|Description|Syntax|#{syntax.id}|#{description}" end def human_readable_format(object) case object when Array "[#{object.collect {|value| human_readable_format(value)}.join(', ')}]" when Hash formatted_values = [] object.each do |key, value| formatted_values << [human_readable_format(key), human_readable_format(value)].join("=>") end "{#{formatted_values.join(', ')}}" else if object.respond_to?(:to_human_readable_format) object.to_human_readable_format else object.inspect end end end end end end activeldap-5.2.4/lib/active_ldap/ldap_controls.rb0000644000004100000410000000061713464071751022113 0ustar www-datawww-datamodule ActiveLdap module LdapControls PAGED_RESULTS = "1.2.840.113556.1.4.319" ASSERTION = "1.3.6.1.1.12" PRE_READ = "1.3.6.1.1.13.1" POST_READ = "1.3.6.1.1.13.2" SUBENTRIES = "1.3.6.1.4.1.4203.1.10.1" MANAGE_DSA_IT = "2.16.840.1.113730.3.4.2" PROXIED_AUTHORIZATION = "2.16.840.1.113730.3.4.18" end end activeldap-5.2.4/lib/active_ldap/callbacks.rb0000644000004100000410000000327013464071751021165 0ustar www-datawww-datarequire 'active_support/core_ext/array/wrap' module ActiveLdap module Callbacks extend ActiveSupport::Concern CALLBACKS = [ :after_initialize, :after_find, :after_touch, :before_validation, :after_validation, :before_save, :around_save, :after_save, :before_create, :around_create, :after_create, :before_update, :around_update, :after_update, :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback ] included do extend ActiveModel::Callbacks include ActiveModel::Validations::Callbacks singleton_class.class_eval do prepend CallbackedInstantiatable end define_model_callbacks :initialize, :find, :touch, :only => :after define_model_callbacks :save, :create, :update, :destroy end module ClassMethods def method_added(meth) super if CALLBACKS.include?(meth.to_sym) ActiveSupport::Deprecation.warn("Base##{meth} has been deprecated, please use Base.#{meth} :method instead", caller[0,1]) send(meth.to_sym, meth.to_sym) end end end module CallbackedInstantiatable def instantiate(record) object = super(record) object.run_callbacks(:find) object.run_callbacks(:initialize) object end end def destroy #:nodoc: run_callbacks(:destroy) { super } end def touch(*) #:nodoc: run_callbacks(:touch) { super } end private def create_or_update #:nodoc: run_callbacks(:save) { super } end def create #:nodoc: run_callbacks(:create) { super } end def update(*) #:nodoc: run_callbacks(:update) { super } end end end activeldap-5.2.4/lib/rails/0000755000004100000410000000000013464071751015556 5ustar www-datawww-dataactiveldap-5.2.4/lib/rails/generators/0000755000004100000410000000000013464071751017727 5ustar www-datawww-dataactiveldap-5.2.4/lib/rails/generators/active_ldap/0000755000004100000410000000000013464071751022202 5ustar www-datawww-dataactiveldap-5.2.4/lib/rails/generators/active_ldap/scaffold/0000755000004100000410000000000013464071751023763 5ustar www-datawww-dataactiveldap-5.2.4/lib/rails/generators/active_ldap/scaffold/scaffold_generator.rb0000644000004100000410000000044313464071751030140 0ustar www-datawww-datarequire 'rails/generators' module ActiveLdap module Generators class ScaffoldGenerator < Rails::Generators::Base source_root File.expand_path('../templates', __FILE__) def create_ldap_yml copy_file 'ldap.yml', 'config/ldap.yml' end end end end activeldap-5.2.4/lib/rails/generators/active_ldap/scaffold/templates/0000755000004100000410000000000013464071751025761 5ustar www-datawww-dataactiveldap-5.2.4/lib/rails/generators/active_ldap/scaffold/templates/ldap.yml0000644000004100000410000000056313464071751027430 0ustar www-datawww-datadevelopment: host: 127.0.0.1 base: dc=devel,dc=local,dc=net bind_dn: cn=admin,dc=local,dc=net password: secret test: host: 127.0.0.1 base: dc=test,dc=local,dc=net bind_dn: cn=admin,dc=local,dc=net password: secret production: host: 127.0.0.1 method: :tls base: dc=production,dc=local,dc=net bind_dn: cn=admin,dc=local,dc=net password: secret activeldap-5.2.4/lib/rails/generators/active_ldap/model/0000755000004100000410000000000013464071751023302 5ustar www-datawww-dataactiveldap-5.2.4/lib/rails/generators/active_ldap/model/templates/0000755000004100000410000000000013464071751025300 5ustar www-datawww-dataactiveldap-5.2.4/lib/rails/generators/active_ldap/model/templates/model_active_ldap.rb0000644000004100000410000000010313464071751031252 0ustar www-datawww-dataclass <%= class_name %> < ActiveLdap::Base <%= ldap_mapping %> end activeldap-5.2.4/lib/rails/generators/active_ldap/model/model_generator.rb0000644000004100000410000000277613464071751027011 0ustar www-datawww-datarequire 'rails/generators' require 'active_ldap' module ActiveLdap module Generators class ModelGenerator < Rails::Generators::NamedBase include ActiveLdap::GetTextSupport source_root File.expand_path('../templates', __FILE__) class_option :dn_attribute, :type => :string, :default => 'cn', :desc => _("Use ATTRIBUTE as default DN attribute for " \ "instances of this model") class_option :prefix, :type => :string, :desc => _("Use PREFIX as prefix for this model") class_option :classes, :type => :array, :default => nil, :desc => _("Use CLASSES as required objectClass for instances of this model") def create_model template 'model_active_ldap.rb', File.join('app/models', class_path, "#{file_name}.rb") end hook_for :test_framework, :as => :model private def prefix options[:prefix] || default_prefix end def default_prefix "ou=#{name.demodulize.pluralize}" end def ldap_mapping(indent=' ') mapping = "ldap_mapping " mapping_options = ["dn_attribute: #{options[:dn_attribute].dump}"] mapping_options << "prefix: #{prefix.dump}" if options[:classes] mapping_options << "classes: #{options[:classes].inspect}" end mapping_options = mapping_options.join(",\n#{indent}#{' ' * mapping.size}") "#{indent}#{mapping}#{mapping_options}" end end end end activeldap-5.2.4/lib/rails/generators/active_ldap/model/USAGE0000644000004100000410000000120713464071751024071 0ustar www-datawww-dataDescription: The model_active_ldap generator creates stubs for a new model. The generator takes a model name as its argument. The model name may be given in CamelCase or under_score and should not be suffixed with 'Model'. The generator creates a model class in app/models, a test suite in test/unit, and test fixtures in test/fixtures/singular_name.yml. It will not create a migration. Examples: rails generate active_ldap:model user This will create a User model: Model: app/models/user.rb Test: test/unit/user_test.rb Fixtures: test/fixtures/users.yml activeldap-5.2.4/.yardopts0000644000004100000410000000020513464071751015541 0ustar www-datawww-data--title ActiveLdap --charset UTF-8 --readme README.textile --files doc/text/**/* --output-dir doc/reference/en --exclude /templates/ activeldap-5.2.4/doc/0000755000004100000410000000000013464071751014443 5ustar www-datawww-dataactiveldap-5.2.4/doc/text/0000755000004100000410000000000013464071751015427 5ustar www-datawww-dataactiveldap-5.2.4/doc/text/rails.textile0000644000004100000410000000700613464071751020144 0ustar www-datawww-datah1. Rails ActiveLdap supports Rails 4.0 or later. h2. Install To install, simply add the following code to your Gemfile:
gem 'activeldap', :require => 'active_ldap/railtie'
You should also depend on an LDAP adapter such as Net::LDAP or Ruby/LDAP. The following example uses Ruby/LDAP:
gem 'ruby-ldap'
Bundler will install the gems automatically when you run 'bundle install'. h2. Configuration You can use a LDAP configuration per environment. They are in a file named 'ldap.yml' in the config directory of your rails app. This file has a similar function to the 'database.yml' file that allows you to set your database connection configurations per environment. Similarly, the ldap.yml file allows configurations to be set for development, test, and production environments. You can generate 'config/ldap.yml' by the following command:
% script/rails generate active_ldap:scaffold
You need to modify 'config/ldap.yml' generated by active_ldap:scaffold. For instance, the development entry would look something like the following:
!!!plain
development:
  host: 127.0.0.1
  port: 389
  base: dc=localhost
  bind_dn: cn=admin,dc=localhost
  password: secret
When your application starts up, ActiveLdap::Base.setup_connection will be called with the parameters specified for your current environment. You can replace default orm generators with gems one to skip active_ldap prefix in 'config/application.rb':
config.app_generators.orm :active_ldap
h2. Model You can generate a User model that represents entries under ou=Users by the following command:
% script/rails generate active_ldap:model User --dn-attribute uid --classes person PosixAccount
It generates the following app/model/user.rb:
class User < ActiveLdap::Base
  ldap_mapping :dn_attribute => "uid",
               :prefix => "ou=Users",
               :classes => ["person", "PosixAccount"]
end
You can add relationships by modifying app/model/user.rb:
class User < ActiveLdap::Base
  ldap_mapping :dn_attribute => 'uid',
               :prefix => "ou=Users",
               :classes => ['person', 'posixAccount']
  belongs_to :primary_group,
             :class_name => "Group",
             :foreign_key => "gidNumber",
             :primary_key => "gidNumber"
  belongs_to :groups,
             :many => 'memberUid'
end
You can also generate a Group model by the following command:
% script/rails generate active_ldap:model Group --classes PosixGroup
app/model/group.rb:
class Group < ActiveLdap::Base
  ldap_mapping :dn_attribute => "cn",
               :prefix => "ou=Groups",
               :classes => ["PosixGroup"]
end
You can add relationships by modifying app/model/group.rb:
class Group < ActiveLdap::Base
  ldap_mapping :dn_attribute => "cn",
               :prefix => "ou=Groups",
               :classes => ["PosixGroup"]
  has_many :members,
           :class_name => "User",
           :wrap => "memberUid"
  has_many :primary_members,
           :class_name => "Group",
           :foreign_key => "gidNumber",
           :primary_key => "gidNumber"
end
You can also generate a Ou model by the following command:
% script/rails generate active_ldap:model Ou --prefix '' --classes organizationalUnit
class Ou < ActiveLdap::Base
  ldap_mapping :dn_attribute => "cn",
               :prefix => "",
               :classes => ["organizationalUnit"]
end
activeldap-5.2.4/doc/text/development.textile0000644000004100000410000000260713464071751021356 0ustar www-datawww-datah1. Development Here is information for developers. h2. Repository ActiveLdap uses ["git repository on GitHub":https://github.com/activeldap]. Here is a list to get each source code. - "activeldap":https://github.com/activeldap/activeldap :=
% git clone https://github.com/activeldap/activeldap.git
=: - "al-admin":https://github.com/activeldap/al-admin :=
% git clone https://github.com/activeldap/al-admin.git
=: h2. Issues ActiveLdap uses "Issues on GitHub":https://github.com/activeldap/activeldap/issues for issue tracking. Please submit a issue when you find an issue. h2. Rails 3 support Here is design about Rails 3 support. h3. must * We add active_ldap/test_help.rb to support ActiveLdap fixture. We don't write same codes into test_helper.rb like http://ruby-activeldap.rubyforge.org/activeldap-fabrication/en/#Install h3. may * We support Warden. * We support Devise * We support OmniAuth. (instead of Warden) h3. DONE * We don't support Rails 3.0.x. * We provide active_ldap/railtie to initialize ActiveLdap. * We remove ActiveRecord dependency. * We depend on ActiveModel instead of ActiveRecord. * We target to Rails 3.1.0. (Yes, it's not released yet but it will be released before we support Rails 3.x.) * We update the documentation and ensure that the procedure for including ActiveLdap in a Rails 3 project is correct. activeldap-5.2.4/doc/text/tutorial.textile0000644000004100000410000010110713464071751020672 0ustar www-datawww-datah1. Tutorial h2. Introduction ActiveLdap is a novel way of interacting with LDAP. Most interaction with LDAP is done using clunky LDIFs, web interfaces, or with painful APIs that required a thick reference manual nearby. ActiveLdap aims to fix that. Inspired by "ActiveRecord":http://activerecord.rubyonrails.org, ActiveLdap provides an object oriented interface to LDAP entries. The target audience is system administrators and LDAP users everywhere that need quick, clean access to LDAP in Ruby. h3. What's LDAP? LDAP stands for "Lightweight Directory Access Protocol." Basically this means that it is the protocol used for accessing LDAP servers. LDAP servers lightweight directories. An LDAP server can contain anything from a simple digital phonebook to user accounts for computer systems. More and more frequently, it is being used for the latter. My examples in this text will assume some familiarity with using LDAP as a centralized authentication and authorization server for Unix systems. (Unfortunately, I've yet to try this against Microsoft's ActiveDirectory, despite what the name implies.) Further reading: * "RFC1777":http://www.faqs.org/rfcs/rfc1777.html - Lightweight Directory Access Protocol * "OpenLDAP":http://www.openldap.org h3. So why use ActiveLdap? Using LDAP directly (even with the excellent Ruby/LDAP), leaves you bound to the world of the predefined LDAP API. While this API is important for many reasons, having to extract code out of LDAP search blocks and create huge arrays of LDAP.mod entries make code harder to read, less intuitive, and just less fun to write. Hopefully, ActiveLdap will remedy all of these problems! h2. Getting Started h3. Requirements * A Ruby implementation: "Ruby":http://www.ruby-lang.org 1.8.x, 1.9.1 or "JRuby":http://jruby.codehaus.org/ * A LDAP library: "Ruby/LDAP":http://code.google.com/p/ruby-activeldap/wiki/RubyLDAP (for Ruby), "Net::LDAP":http://rubyforge.org/projects/net-ldap/ (for Ruby or JRuby) or JNDI (for JRuby) * A LDAP server: "OpenLDAP":http://www.openldap.org, etc ** Your LDAP server must allow root_dse queries to allow for schema queries h3. Installation Assuming all the requirements are installed, you can install by gem.
!!!plain
# gem install activeldap
Now as a quick test, you can run:
$ irb -rubygems
irb> require 'active_ldap'
=> true
irb> exit
If the require returns false or an exception is raised, there has been a problem with the installation. You may need to customize what setup.rb does on install. h2. Usage This section covers using ActiveLdap from writing extension classes to writing applications that use them. Just to give a taste of what's to come, here is a quick example using irb:
irb> require 'active_ldap'
Call setup_connection method for connect to LDAP server. In this case, LDAP server is localhost, and base of LDAP tree is "dc=dataspill,dc=org".
irb> ActiveLdap::Base.setup_connection :host => 'localhost', :base => 'dc=dataspill,dc=org'
Here's an extension class that maps to the LDAP Group objects:
irb> class Group < ActiveLdap::Base
irb*   ldap_mapping
irb* end
In the above code, Group class handles sub tree of ou=Groups tha is :base value specified by setup_connection. A instance of Group class represents a LDAP object under ou=Gruops. Here is the Group class in use:
# Get all group names
irb> all_groups = Group.find(:all, '*').collect {|group| group.cn}
=> ["root", "daemon", "bin", "sys", "adm", "tty", ..., "develop"]

# Get LDAP objects in develop group
irb> group = Group.find("develop")
=> # ...>

# Get cn of the develop group
irb> group.cn
=> "develop"

# Get gid_number of the develop group
irb> group.gid_number
=> "1003"
That's it! No let's get back in to it. h3. Extension Classes Extension classes are classes that are subclassed from ActiveLdap::Base. They are used to represent objects in your LDAP server abstractly. h4. Why do I need them? Extension classes are what make ActiveLdap "active"! They do all the background work to make easy-to-use objects by mapping the LDAP object's attributes on to a Ruby class. h4. Special Methods I will briefly talk about each of the methods you can use when defining an extension class. In the above example, I only made one special method call inside the Group class. More than likely, you will want to more than that. h5. ldap_mapping ldap_mapping is the only required method to setup an extension class for use with ActiveLdap. It must be called inside of a subclass as shown above. Below is a much more realistic Group class:
class Group < ActiveLdap::Base
  ldap_mapping :dn_attribute => 'cn',
               :prefix => 'ou=Groups', :classes => ['top', 'posixGroup'],
               :scope => :one
end
As you can see, this method is used for defining how this class maps in to LDAP. Let's say that my LDAP tree looks something like this:
!!!plain
* dc=dataspill,dc=org
|- ou=People,dc=dataspill,dc=org
|+ ou=Groups,dc=dataspill,dc=org
  \
   |- cn=develop,ou=Groups,dc=dataspill,dc=org
   |- cn=root,ou=Groups,dc=dataspill,dc=org
   |- ...
Under ou=People I store user objects, and under ou=Groups, I store group objects. What |ldap_mapping| has done is mapped the class in to the LDAP tree abstractly. With the given :dn_attributes and :prefix, it will only work for entries under ou=Groups,dc=dataspill,dc=org using the primary attribute 'cn' as the beginning of the distinguished name. Just for clarity, here's how the arguments map out:
!!!plain
 cn=develop,ou=Groups,dc=dataspill,dc=org
 ^^         ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
:dn_attribute |         |
            :prefix     |
              :base from setup_connection
:scope tells ActiveLdap to only search under ou=Groups, and not to look deeper for dn_attribute matches. (e.g. cn=develop,ou=DevGroups,ou=Groups,dc=dataspill,dc=org) You can choose value from between :sub, :one and :base. Something's missing: :classes. :classes is used to tell ActiveLdap what the minimum requirement is when creating a new object. LDAP uses objectClasses to define what attributes a LDAP object may have. ActiveLdap needs to know what classes are required when creating a new object. Of course, you can leave that field out to default to ['top'] only. Then you can let each application choose what objectClasses their objects should have by calling the method e.g. Group#add_class(*values). Note that is can be very important to define the default :classes value. Due to implementation choices with most LDAP servers, once an object is created, its structural objectclasses may not be removed (or replaced). Setting a sane default may help avoid programmer error later. :classes isn't the only optional argument. If :dn_attribute is left off, it defaults to super class's value or 'cn'. If :prefix is left off, it will default to 'ou=PluralizedClassName'. In this case, it would be 'ou=Groups'. :classes should be an Array. :dn_attribute should be a String and so should :prefix. h5. belongs_to This method allows an extension class to make use of other extension classes tying objects together across the LDAP tree. Often, user objects will be members of, or belong_to, Group objects.
!!!plain
* dc=dataspill,dc=org
|+ ou=People,dc=dataspill,dc=org
 \
 |- uid=drewry,ou=People,dc=dataspill,dc=org
|- ou=Groups,dc=dataspill,dc=org
In the above tree, one such example would be user 'drewry' who is a part of the group 'develop'. You can see this by looking at the 'memberUid' field of 'develop'.
irb> develop = Group.find('develop')
=> ...
irb> develop.memberUid
=> ['drewry', 'builder']
If we look at the LDAP entry for 'drewry', we do not see any references to group 'develop'. In order to remedy that, we can use belongs_to
irb> class User < ActiveLdap::Base
irb*   ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=People', :classes => ['top','account']
irb*   belongs_to :groups, :class_name => 'Group', :many => 'memberUid', :foreign_key => 'uid'
irb* end
Now, class User will have a method called 'groups' which will retrieve all Group objects that a user is in.
irb> me = User.find('drewry')
irb> me.groups
=>  #    # Enumerable object
irb> me.groups.each { |group| p group.cn };nil
"cdrom"
"audio"
"develop"
=> nil
(Note: nil is just there to make the output cleaner...)
TIP: If you weren't sure what the distinguished name attribute was for Group, you could also do the following:
irb> me.groups.each { |group| p group.id };nil
"cdrom"
"audio"
"develop"
=> nil
Now let's talk about the arguments of belongs_to. We use the following code that extends Group group a bit for explain:
class User < ActiveLdap::Base
  ldap_mapping :dn_attribute => 'uid', :prefix => 'People', :classes => ['top','account']

  # Associate with primary belonged group
  belongs_to :primary_group, :foreign_key => 'gidNumber',
               :class_name => 'Group', :primary_key => 'gidNumber'

  # Associate with all belonged groups
  belongs_to :groups,  :foreign_key => 'uid',
               :class_name => 'Group', :many => 'memberUid',
end
The first argument is the name of the method you wish to create. In this case, we created a method called primary_group and groups using the symbol :primary_group and :groups. The next collection of arguments are actually a Hash (as with ldap_mapping). :foreign_key tells belongs_to what attribute Group objects have that match the related object's attribute. If :foreign_key is left off of the argument list, it is assumed to be the dn_attribute. In the example, uid is used for :foreign_key. It may confuse you. ActiveLdap uses :foreign_key as "own attribute name". So it may not be "foreign key". You can consider :foreign_key just as a relation key. :primary_key is treated as "related object's attribute name" as we discussed later. :class_name should be a string that has the name of a class you've already included. If your class is inside of a module, be sure to put the whole name, e.g. @:class_name => "MyLdapModule::Group"@. :many and :primary_key are similar. Both of them specifies attribute name of related object specified by :foreign_key. Those values are attribute name that can be used by object of class specified by :class_name. Relation is resolved by searching entries of :class_name class with :foreign_key attribute value. Search target attribute for it is :primary_key or :many. primary_group method in the above example searches Group objects with User object's gidNumber value as Group object's gidNumber value. Matched Group objects are belonged objects. :parimary_key is used for an object just belongs to an object. The first matched object is treated as beloned object. :many is used for an object belongs to many objects. All of matched objects are treated as belonged objects. h5. has_many This method is the opposite of belongs_to. Instead of checking other objects in other parts of the LDAP tree to see if you belong to them, you have multiple objects from other trees listed in your object. To show this, we can just invert the example from above:
class Group < ActiveLdap::Base
  ldap_mapping :dn_attribute => 'cn', :prefix => 'ou=Groups', :classes => ['top', 'posixGroup']

  # Associate with primary belonged users
  has_many :primary_members, :foreign_key => 'gidNumber',
           :class_name => "User", :primary_key => 'gidNumber'

  # Associate with all belonged users
  has_many :members,  :wrap => "memberUid",
           :class_name => "User",  :primary_key => 'uid'
end
Now we can see that group develop has user 'drewry' as a member, and it can even return all responses in object form just like belongs_to methods.
irb> develop = Group.find('develop')
=> ...
irb> develop.members
=> # # Enumerable object
irb> develop.members.map{|member| member.id}
=> ["drewry", "builder"]
The arguments for has_many follow the exact same idea that belongs_to's arguments followed. :wrap's contents are used to search for matching :primary_key content. If :primary_key is not specified, it defaults to the dn_attribute of the specified :class_name. h3. Using these new classes These new classes have many method calls. Many of them are automatically generated to provide access to the LDAP object's attributes. Other were defined during class creation by special methods like belongs_to. There are a few other methods that do not fall in to these categories. h4. .find .find is a class method that is accessible from any subclass of Base that has 'ldap_mapping' called. When called .first(:first) returns the first match of the given class.
irb> Group.find(:first, 'deve*").cn
=> "develop"
In this simple example, Group.find took the search string of 'deve*' and searched for the first match in Group where the dn_attribute matched the query. This is the simplest example of .find.
irb> Group.find(:all).collect {|group| group.cn}
=> ["root", "daemon", "bin", "sys", "adm", "tty", ..., "develop"]
Here .find(:all) returns all matches to the same query. Both .find(:first) and .find(:all) also can take more expressive arguments:
irb> Group.find(:all, :attribute => 'gidNumber', :value => '1003').collect {|group| group.cn}
=> ["develop"]
So it is pretty clear what :attribute and :value do - they are used to query as :attribute=:value. If :attribute is unspecified, it defaults to the dn_attribute. It is also possible to override :attribute and :value by specifying :filter. This argument allows the direct specification of a LDAP filter to retrieve objects by. h5. Using the :filter option The filter option lets you pass in an LDAP query string. For example retrieving all groups with cn which starts with @'dev'@ and has @guid@ == 1:
irb> Group.find(:all, :filter => '(&(cn=dev*)(guid=1))').collect {|group| group.cn}
=> ["develop"]
It also allows a hash like sintax (sparing you the need to write the query by hand ):
irb> Group.find(:all, :filter => {:cn => 'dev*', :guid => 1 }).collect {|group| group.cn}
=> ["develop", "developers", "sys", "sysadmin"]
You can build complex queries combining the hash syntax with arrays and @:or@ and @:and@ operators retrieving all users whose name contains 'john' or cn ends with 'smith' or contains 'liz'
irb> User.find(:all, filter: [:or, [:or, { :cn => '*smith', :name => '*john*'} ], { cn: '*liz*' }]).collect(&:cn)
=> ['john.smith', 'jane.smith', 'john tha ripper', 'liz.taylor', ...]
h4. .search .search is a class method that is accessible from any subclass of Base, and Base. It lets the user perform an arbitrary search against the current LDAP connection irrespetive of LDAP mapping data. This is meant to be useful as a utility method to cover 80% of the cases where a user would want to use Base.connection directly.
irb> Base.search(:base => 'dc=example,dc=com', :filter => '(uid=roo*)',
                 :scope => :sub, :attributes => ['uid', 'cn'])
=>  [["uid=root,ou=People,dc=dataspill,dc=org",{"cn"=>["root"], "uidNumber"=>["0"]}]
You can specify the :filter, :base, :scope, and :attributes, but they all have defaults -- * :filter defaults to objectClass=* - usually this isn't what you want * :base defaults to the base of the class this is executed from (as set in ldap_mapping) * :scope defaults to :sub. Usually you won't need to change it (You can choose value also from between :one and :base) * :attributes defaults to [] and is the list of attributes you want back. Empty means all of them. h4. #valid? valid? is a method that verifies that all attributes that are required by the objects current objectClasses are populated. h4. #save save is a method that writes any changes to an object back to the LDAP server. It automatically handles the addition of new objects, and the modification of existing ones. h4. .exists? exists? is a simple method which returns true is the current object exists in LDAP, or false if it does not.
irb> User.exists?("dshadsadsa")
=> false
h3. ActiveLdap::Base ActiveLdap::Base has come up a number of times in the examples above. Every time, it was being used as the super class for the wrapper objects. While this is it's main purpose, it also handles quite a bit more in the background. h4. What is it? ActiveLdap::Base is the heart of ActiveLdap. It does all the schema parsing for validation and attribute-to-method mangling as well as manage the connection to LDAP. h5. setup_connection Base.setup_connection takes many (optional) arguments and is used to connect to the LDAP server. Sometimes you will want to connect anonymously and other times over TLS with user credentials. Base.setup_connection is here to do all of that for you. By default, if you call any subclass of Base, such as Group, it will call Base.setup_connection() if these is no active LDAP connection. If your server allows anonymous binding, and you only want to access data in a read-only fashion, you won't need to call Base.setup_connection. Here is a fully parameterized call:
Base.setup_connection(
  :host => 'ldap.dataspill.org',
  :port => 389,
  :base => 'dc=dataspill,dc=org',
  :logger => logger_object,
  :bind_dn => "uid=drewry,ou=People,dc=dataspill,dc=org",
  :password_block => Proc.new { 'password12345' },
  :allow_anonymous => false,
  :try_sasl => false
)
There are quite a few arguments, but luckily many of them have safe defaults: * :host defaults to "127.0.0.1". * :port defaults to nil. 389 is applied if not specified. * :bind_dn defaults to nil. anonymous binding is applied if not specified. * :logger defaults to a Logger object that prints fatal messages to stderr * :password_block defaults to nil * :allow_anonymous defaults to true * :try_sasl defaults to false - see Advanced Topics for more on this one. Most of these are obvious, but I'll step through them for completeness: * :host defines the LDAP server hostname to connect to. * :port defines the LDAP server port to connect to. * :method defines the type of connection - :tls, :ssl, :plain * :base specifies the LDAP search base to use with the prefixes defined in all subclasses. * :bind_dn specifies what your server expects when attempting to bind with credentials. * :logger accepts a custom logger object to integrate with any other logging your application uses. * :password_block, if defined, give the Proc block for acquiring the password * :password, if defined, give the user's password as a String * :store_password indicates whether the password should be stored, or if used whether the :password_block should be called on each reconnect. * :allow_anonymous determines whether anonymous binding is allowed if other bind methods fail * :try_sasl, when true, tells ActiveLdap to attempt a SASL-GSSAPI bind * :sasl_quiet, when true, tells the SASL libraries to not spew messages to STDOUT * :sasl_options, if defined, should be a hash of options to pass through. This currently only works with the ruby-ldap adapter, which currently only supports :realm, :authcid, and :authzid. * :retry_limit - indicates the number of attempts to reconnect that will be undertaken when a stale connection occurs. -1 means infinite. * :retry_wait - seconds to wait before retrying a connection * :scope - dictates how to find objects. (Default: :one) * :timeout - time in seconds - defaults to disabled. This CAN interrupt search() requests. Be warned. * :retry_on_timeout - whether to reconnect when timeouts occur. Defaults to true See lib/configuration.rb(ActiveLdap::Configuration::DEFAULT_CONFIG) for defaults for each option Base.setup_connection just setups connection configuration. A connection is connected and bound when it is needed. It follows roughly the following approach: * Connect to host:port using :method * If bind_dn and password_block/password, attempt to bind with credentials. * If that fails or no password_block and anonymous allowed, attempt to bind anonymously. * If that fails, error out. On connect, the configuration options passed in are stored in an internal class variable which is used to cache the information without ditching the defaults passed in from configuration.rb h5. connection Base.connection returns the ActiveLdap::Connection object. h3. Exceptions There are a few custom exceptions used in ActiveLdap. They are detailed below. h4. DeleteError This exception is raised when #delete fails. It will include LDAP error information that was passed up during the error. h4. SaveError This exception is raised when there is a problem in #save updating or creating an LDAP entry. Often the error messages are cryptic. Looking at the server logs or doing an "Wireshark":http://www.wireshark.org dump of the connection will often provide better insight. h4. AuthenticationError This exception is raised during Base.setup_connection if no valid authentication methods succeeded. h4. ConnectionError This exception is raised during Base.setup_connection if no valid connection to the LDAP server could be created. Check you Base.setup_connection arguments, and network connectivity! Also check your LDAP server logs to see if it ever saw the request. h4. ObjectClassError This exception is raised when an object class is used that is not defined in the schema. h3. Others Other exceptions may be raised by the Ruby/LDAP module, or by other subsystems. If you get one of these exceptions and think it should be wrapped, write me an email and let me know where it is and what you expected. For faster results, email a patch! h3. Putting it all together Now that all of the components of ActiveLdap have been covered, it's time to put it all together! The rest of this section will show the steps to setup example user and group management scripts for use with the LDAP tree described above. All of the scripts here are in the package's examples/ directory. h4. Setting up Create directory for scripts.
!!!plain
% mkdir -p ldapadmin/objects
In ldapadmin/objects/ create the file user.rb:
require 'objects/group'

class User < ActiveLdap::Base
  ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=People', :classes => ['person', 'posixAccount']
  belongs_to :groups, :class_name => 'Group', :many => 'memberUid'
end
In ldapadmin/objects/ create the file group.rb:
class Group < ActiveLdap::Base
  ldap_mapping :classes => ['top', 'posixGroup'], :prefix => 'ou=Groups'
  has_many :members, :class_name => "User", :wrap => "memberUid"
  has_many :primary_members, :class_name => 'User', :foreign_key => 'gidNumber', :primary_key => 'gidNumber'
end
Now, we can write some small scripts to do simple management tasks. h4. Creating LDAP entries Now let's create a really dumb script for adding users - ldapadmin/useradd:
#!/usr/bin/ruby -W0

base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
$LOAD_PATH << File.join(base, "lib")
$LOAD_PATH << File.join(base, "examples")

require 'rubygems'
require 'active_ldap'
require 'objects/user'
require 'objects/group'

argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
  opts.banner += " USER_NAME CN UID"
end

if argv.size == 3
  name, cn, uid = argv
else
  $stderr.puts opts
  exit 1
end

pwb = Proc.new do |user|
  ActiveLdap::Command.read_password("[#{user}] Password: ")
end

ActiveLdap::Base.setup_connection(:password_block => pwb,
                                  :allow_anonymous => false)

if User.exists?(name)
  $stderr.puts("User #{name} already exists.")
  exit 1
end

user = User.new(name)
user.add_class('shadowAccount')
user.cn = cn
user.uid_number = uid
user.gid_number = uid
user.home_directory = "/home/#{name}"
user.sn = "somesn"
unless user.save
  puts "failed"
  puts user.errors.full_messages
  exit 1
end
h4. Managing LDAP entries Now let's create another dumb script for modifying users - ldapadmin/usermod:
#!/usr/bin/ruby -W0

base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
$LOAD_PATH << File.join(base, "lib")
$LOAD_PATH << File.join(base, "examples")

require 'rubygems'
require 'active_ldap'
require 'objects/user'
require 'objects/group'

argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
  opts.banner += " USER_NAME CN UID"
end

if argv.size == 3
  name, cn, uid = argv
else
  $stderr.puts opts
  exit 1
end

pwb = Proc.new do |user|
  ActiveLdap::Command.read_password("[#{user}] Password: ")
end

ActiveLdap::Base.setup_connection(:password_block => pwb,
                                  :allow_anonymous => false)

unless User.exists?(name)
  $stderr.puts("User #{name} doesn't exist.")
  exit 1
end

user = User.find(name)
user.cn = cn
user.uid_number = uid
user.gid_number = uid
unless user.save
  puts "failed"
  puts user.errors.full_messages
  exit 1
end
h4. Removing LDAP entries Now let's create more one for deleting users - ldapadmin/userdel:
#!/usr/bin/ruby -W0

base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
$LOAD_PATH << File.join(base, "lib")
$LOAD_PATH << File.join(base, "examples")

require 'rubygems'
require 'active_ldap'
require 'objects/user'
require 'objects/group'

argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
  opts.banner += " USER_NAME"
end

if argv.size == 1
  name = argv.shift
else
  $stderr.puts opts
  exit 1
end

pwb = Proc.new do |user|
  ActiveLdap::Command.read_password("[#{user}] Password: ")
end

ActiveLdap::Base.setup_connection(:password_block => pwb,
                                  :allow_anonymous => false)

unless User.exists?(name)
  $stderr.puts("User #{name} doesn't exist.")
  exit 1
end

User.destroy(name)
h3. Advanced Topics Below are some situation tips and tricks to get the most out of ActiveLdap. h4. Binary data and other subtypes Sometimes, you may want to store attributes with language specifiers, or perhaps in binary form. This is (finally!) fully supported. To do so, follow the examples below:
irb> user = User.new('drewry')
=> ...
# This adds a cn entry in lang-en and whatever the server default is.
irb> user.cn = [ 'wad', {'lang-en' => ['wad', 'Will Drewry']} ]
=> ...
irb> user.cn
=> ["wad", {"lang-en-us" => ["wad", "Will Drewry"]}]
# Now let's add a binary X.509 certificate (assume objectClass is correct)
irb> user.user_certificate = File.read('example.der')
=> ...
irb> user.save
So that's a lot to take in. Here's what is going on. I just set the LDAP object's cn to "wad" and cn:lang-en-us to ["wad", "Will Drewry"]. Anytime a LDAP subtype is required, you must encapsulate the data in a Hash. But wait a minute, I just read in a binary certificate without wrapping it up. So any binary attribute _that requires ;binary subtyping_ will automagically get wrapped in @{'binary' => value}@ if you don't do it. This keeps your #writes from breaking, and my code from crying. For correctness, I could have easily done the following:
irb> user.user_certificate = {'binary' => File.read('example.der')}
You should note that some binary data does not use the binary subtype all the time. One example is jpegPhoto. You can use it as jpegPhoto;binary or just as jpegPhoto. Since the schema dictates that it is a binary value, ActiveLdap will write it as binary, but the subtype will not be automatically appended as above. The use of the subtype on attributes like jpegPhoto is ultimately decided by the LDAP site policy and not by any programmatic means. The only subtypes defined in LDAPv3 are lang-* and binary. These can be nested though:
irb> user.cn = [{'lang-ja' => {'binary' => 'some Japanese'}}]
As I understand it, OpenLDAP does not support nested subtypes, but some documentation I've read suggests that Netscape's LDAP server does. I only have access to OpenLDAP. If anyone tests this out, please let me know how it goes! And that pretty much wraps up this section. h4. Further integration with your environment aka namespacing If you want this to cleanly integrate into your system-wide Ruby include path, you should put your extension classes inside a custom module. Example: ./myldap.rb:
require 'active_ldap'
require 'myldap/user'
require 'myldap/group'
module MyLDAP
end
./myldap/user.rb:
module MyLDAP
  class User < ActiveLdap::Base
    ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=People', :classes => ['top', 'account', 'posixAccount']
    belongs_to :groups, :class_name => 'MyLDAP::Group', :many => 'memberUid'
  end
end
./myldap/group.rb:
module MyLDAP
  class Group < ActiveLdap::Base
    ldap_mapping :classes => ['top', 'posixGroup'], :prefix => 'ou=Groups'
    has_many :members, :class_name => 'MyLDAP::User', :wrap => 'memberUid'
    has_many :primary_members, :class_name => 'MyLDAP::User', :foreign_key => 'gidNumber', :primary_key => 'gidNumber'
  end
end
Now in your local applications, you can call
require 'myldap'

MyLDAP::Group.new('foo')
...
and everything should work well. h4. force array results for single values Even though ActiveLdap attempts to maintain programmatic ease by returning Array values only. By specifying 'true' as an argument to any attribute method you will get back a Array if it is single value. Here's an example:
irb> user = User.new('drewry')
=> ...
irb> user.cn(true)
=> ["Will Drewry"]
h4. Dynamic attribute crawling If you use tab completion in irb, you'll notice that you /can/ tab complete the dynamic attribute methods. You can still see which methods are for attributes using Base#attribute_names:
irb> d = Group.new('develop')
=> ...
irb> d.attribute_names
=> ["gidNumber", "cn", "memberUid", "commonName", "description", "userPassword", "objectClass"]
h4. Juggling multiple LDAP connections In the same vein as the last tip, you can use multiple LDAP connections by per class as follows:
irb> anon_class = Class.new(Base)
=> ...
irb> anon_class.setup_connection
=> ...
irb> auth_class = Class.new(Base)
=> ...
irb> auth_class.setup_connection(:password_block => lambda{'mypass'})
=> ...
This can be useful for doing authentication tests and other such tricks. h4. :try_sasl If you have the Ruby/LDAP package with the SASL/GSSAPI patch from Ian MacDonald's web site, you can use Kerberos to bind to your LDAP server. By default, :try_sasl is false. Also note that you must be using OpenLDAP 2.1.29 or higher to use SASL/GSSAPI due to some bugs in older versions of OpenLDAP. h4. Don't be afraid! [Internals] Don't be afraid to add more methods to the extensions classes and to experiment. That's exactly how I ended up with this package. If you come up with something cool, please share it! The internal structure of ActiveLdap::Base, and thus all its subclasses, is still in flux. I've tried to minimize the changes to the overall API, but the internals are still rough around the edges. h5. Where's ldap_mapping data stored? How can I get to it? When you call ldap_mapping, it overwrites several class methods inherited from Base: * Base.base() * Base.required_classes() * Base.dn_attribute() You can access these from custom class methods by calling MyClass.base(), or whatever. There are predefined instance methods for getting to these from any new instance methods you define: * Base#base() * Base#required_classes() * Base#dn_attribute() h5. What else? Well if you want to use the LDAP connection for anything, I'd suggest still calling Base.connection to get it. There really aren't many other internals that need to be worried about. You could get the LDAP schema with Base.schema. The only other useful tricks are dereferencing and accessing the stored data. Since LDAP attributes can have multiple names, e.g. cn or commonName, any methods you write might need to figure it out. I'd suggest just calling self[attribname] to get the value, but if that's not good enough, you can call look up the stored name by #to_real_attribute_name as follows:
irb> User.find(:first).instance_eval do
irb>   to_real_attribute_name('commonName')
irb> end
=> 'cn'
This tells you the name the attribute is stored in behind the scenes (@data). Again, self[attribname] should be enough for most extensions, but if not, it's probably safe to dabble here. Also, if you like to look up all aliases for an attribute, you can call the following:
irb> User.schema.attribute_type 'cn', 'NAME'
=> ["cn", "commonName"]
This is discovered automagically from the LDAP server's schema. h2. Limitations h3. Speed Currently, ActiveLdap could be faster. I have some recursive type checking going on which slows object creation down, and I'm sure there are many, many other places optimizations can be done. Feel free to send patches, or just hang in there until I can optimize away the slowness. h2. Feedback Any and all feedback and patches are welcome. I am very excited about this package, and I'd like to see it prove helpful to more people than just myself. activeldap-5.2.4/doc/text/news.textile0000644000004100000410000011207113464071751020005 0ustar www-datawww-datah1. News h2(#release-5-2-3). 5.2.3: 2019-02-15 h3. Improvements * Changed to use add and delete for modify if it's needed. [GitHub#156][Patch by David Klotz] * Added support for timezone with munites offset such as @0530@. [GitHub#160][GitHub#161][Patch by Neng Xu] * Added support for Ruby 2.6. h3. Thanks * David Klotz * Neng Xu h2(#release-5-2-2). 5.2.2: 2018-07-12 h3. Improvements * Added @:tls_options@ option. [GitHub#156][Patch by David Klotz] h3. Thanks * David Klotz h2(#release-5-2-1). 5.2.1: 2018-06-13 h3. Fixes * Fixed a bug that configuration may be removed unexpectedly. [GitHub#155][Reported by Juha Erkkilä] h3. Thanks * Juha Erkkilä h2(#release-5-2-0). 5.2.0: 2018-05-09 h3. Improvements * Added @:dc_base_class@ and @:ou_base_class@ options to @ActiveLdap::Populate.ensure_base@. [GitHub#153][Patch by hide_24] * Added Active Model 5.2.0 support. * Improved connection error handling for net-ldap. h3. Thanks * hide_24 h2(#release-5-1-1). 5.1.1: 2018-01-17 h3. Improvements * Added @:include_operational_attributes@ convenient option to @ActiveLdap::Base.find@. @ActiveLdap::Base.find(..., :include_operational_attributes => true)@ equals to @ActiveLdap::Base.find(..., :attributes => ["*", "+"])@. [GitHub#150][Reported by jas01] h3. Thanks * jas01 h2(#release-5-1-0). 5.1.0: 2017-05-01 h3. Improvements * Supported Rails 5.1.0. * Supported sub class instantiate by objectClass. [GitHub#134][Patch by Chris Garrigues] * Improved error messages. * Changed to the default LDAP client to net-ldap from ruby-ldap because ruby-ldap doesn't support timeout. * Suppressed warnings. [GitHub#146][Reported by jas01] h3. Fixes * Added missing dependency. [GitHub#145][Reported by Tom Wardrop] h3. Thanks * Chris Garrigues * Tom Wardrop * jas01 h2(#release-4-0-6). 4.0.6: 2016-04-07 h3. Improvements * Updated supported Ruby versions. [GitHub#127] [Patch by weicheng] * Supported spaces in DN. [GitHub#129] [Patch by belltailjp] h3. Thanks * weicheng * belltailjp h2(#release-4-0-5). 4.0.5: 2016-01-20 h3. Improvements * Supported @unicodePwd@ in Active Directory [GitHub#105] [Reported by Laas Toom] * Supported Blowfish, SHA-256 and SHA-512 password hash with salt. [GitHub#108] [Patch by Gary Richards] * Supported Ruby 2.2. [GitHub#115] [Reported by Jan Zikan] [GitHub#125] [Patch by Bohuslav Blín] * Supported Ruby 2.3. h3. Fixes * Fixed documentation for @rails generate@. [GitHub#107] [Patch by Gary Richards] h3. Thanks * Laas Toom * Gary Richards * Jan Zikan * Bohuslav Blín h2(#release-4-0-4). 4.0.4: 2014-10-11 h3. Improvements * Migrated to commit mail mailing list to "Google Groups":https://groups.google.com/forum/?hl=ja#!forum/activeldap-commit from RubyForge. Thanks to RubyForge! RubyForge was very helpful! * Update project homepage URL in README. [GitHub#103] [Patch by Adam Whittingham] * Removed needless @Enumerable@ inclusion in @ActiveLdap::Base@. [GitHub#104] [Patch by Murray Steele] * {ActiveLdap::Populate.ensure_base}: Supported ou entry creation in base DN. * Added @follow_referrals@ configuration. You can disable auto referrals following by specifying @false@. It is useful when you can't access referrals. This configuration is enabled by default. This configuration works only with ruby-ldap adapter. [GitHub#99] [Suggested by hadmut] * Supported @bindname@ extension in LDAP URL such as @ldap://host/dc=base,dc=name????bindname=cn%3Dadmin%2Cdc%3Dexample%2Cdc%3Dcom%3F@. h3. Fixes * Fixed a bug logging is failed on removing a connection. [GitHub#94] [Reported by Francisco Miguel Biete] * Fixed homepage URL in RubyGems. [GitHub#95] [Patch by Vít Ondruch] * Fixed a bug that DN in LDAP URL is used as bind DN not base DN. h3. Thanks * Francisco Miguel Biete * Vít Ondruch * Adam Whittingham * Murray Steele * hadmut h2(#4-0-3). 4.0.3: 2014-05-15 h3. Improvements * Supported stopping colorize logging by @config.colorize_logging = false@. [GitHub:#81] [Reported by nengxu] * Supported PagedResults defined in RFC 2696 in the net-ldap adapter. [activeldap-discuss] Paged results [Suggested by Aaron Knister] * Supported PagedResults defined in RFC 2696 in the ldap adapter. [GitHub#83] [Patch by Aaron Knister] * Stopped to override ORM generator by default. [GitHub#87] [Patch by Josef Šimánek] * Supported Rails 4.1.0. [GitHub#90] [Patch by Francisco Miguel Biete] * document: Removed obsoleted description. [activeldap-discuss] [Reported by Jarod Watkins] * Supported @ActiveLdap::Base.attribute_method?@ . [GitHub#92] [Reported by Renaud Chaput] h3. Fixes * Fixed a bug that @belongs_to :many@ 's inconsistent behavior. You get DN attribute when you add an entry by DN attribute to belongs_to :many collection. It should return entry object instead of DN attribute. Because loaded collection returns entry objects. [activeldap-discuss] [Reported by Jarod Watkins] h3. Thanks * nengxu * Aaron Knister * Josef Šimánek * Francisco Miguel Biete * Jarod Watkins * Renaud Chaput h2(#4-0-2). 4.0.2: 2014-01-04 h3. Improvements * Supported sub-tree moving by all adapters. * Used YARD style link in documentation. [Reported by Fraser McCrossan] * Supported Object-Security-Descriptor (OID: 1.2.840.113556.1.4.907) [GitHub:#66] [Reported by Nowhere Man] * Made JEPG syntax binary. * Supported binary encoding for values in a container. [GitHub:#66] [Reported by Nowhere Man] * Added documentation about @:filter@ option of {ActiveLdap::Base.find} into tutorial. [GitHub:#72] [Patch by Fernando Martinez] * Migrated to gettext gem from gettext_i18n_rails gem because ActiveLdap dosen't use any gettext_i18n_rails gem features.. [activeldap-discuss] [Reported by Christian Nennemann] * Supported retry on timeout on JNDI adapter. [GitHub:#77] [Patch by Ryosuke Yamazaki] h3. Fixes * Removed needless newlines generated by @pack("m")@. [GitHub:#75] [GitHub:#76] [Patch by Ryosuke Yamazaki] * Fixed a bug that @after_initialize@ isn't run. [GitHub:#79] [Patch by Nobutaka OSHIRO] h3. Thanks * Fraser McCrossan * Nowhere Man * Fernando Martinez * Christian Nennemann * Ryosuke Yamazaki * Nobutaka OSHIRO h2(#4-0-1). 4.0.1: 2013-08-29 h3. Improvements * Added ActiveLdap::EntryAttribute#exist?. * [GitHub:#66] Improved Active Directory support. Binary data can be validated correctly. [Reported by Nowhere Man] * [GitHub:#6][GitHub:#69] Improved setup description in tutorial. [Reported by Radosław Antoniuk] [Patch by Francisco Miguel Biete] * [GitHub:#56] Supported moving sub-tree. It requires Ruby/LDAP 0.9.13 or later, JRuby or net-ldap 0.5.0 or later. (net-ldap 0.5.0 isn't released yet.) [Reported by Jean-François Rioux] h3. Fixes * [GitHub:#65] Removed removed attributes values by removing objectClasses. [Reported by mbab] h3. Thanks * mbab * Nowhere Man * Radosław Antoniuk * Francisco Miguel Biete * Jean-François Rioux h2(#4-0-0). 4.0.0: 2013-07-13 h3. Improvements * [activeldap-discuss] Added {ActiveLdap::Entry} for convenient. [Suggested by Craig White] * [GitHub:#45] Ensured that {ActiveLdap::Persistence#save!} returns true on success. But you should use {ActiveLdap::Persistence#save} to determine success or failure by return value. [Reported by Suggested by Erik M Jacobs] * [GitHub:#52] Improved binary data handling on Ruby 1.9.3. [Patch by Carl P. Corliss] * [GitHub:#53] Supported lower case hashed password. [Patch by jpiotro3] * [GitHub:#51] Supported implicit railtie load by @require "active_ldap"@. [Patch by mperrando] * [GitHub:#62] Improved JNDI communication error handling. [Patch by Ryosuke Yamazaki] * [GitHub:#61] Supported Rails 4. Dropped Rails 3 support. [Patch by superscott] * [GitHub:#63] Handled Errno::ECONNRESET as connection in net-ldap adapter [Patch by mpoornima] h3. Fixes * [GitHub:#44] Fixed a typo in document. [Patch by Vaucher Philippe] * [GitHub:#50] Fixed a stack overflow during SASL bind to a unresponsive LDAP server. [Patch by pwillred] * [GitHub:#54] Fixed a link in document. [Patch by marco] * [GitHub:#57] Fixed a wrong blank value detection for "false". [Reported by Robin Doer] h3. Thanks * Craig White * Vaucher Philippe * Erik M Jacobs * pwillred * Carl P. Corliss * jpiotro3 * marco * mperrando * Robin Doer * Ryosuke Yamazaki * superscott * mpoornima h2(#3-2-2). 3.2.2: 2012-09-01 * Supported entry creation by direct ActiveLdap::Base use. [Reported by Craig White] * Started to use Travis CI. h3. Thanks * Craig White h2(#3-2-1). 3.2.1: 2012-08-31 * Fixed a bug that ActiveLdap::Base#delete doesn't work. [Reported by Craig White] h3. Thanks * Craig White h2(#3-2-0). 3.2.0: 2012-08-29 * [GitHub:#39] Supported Rails 3.2.8. [Reported by Ben Langfeld] * [GitHub:#13] Don't use deprecated Gem.available?. [Patch by sailesh] * [GitHub:#19] Supported new entry by @ha_many :wrap@. [Patch by Alex Tomlins] * Supported @:only@ option in XML output. * [GitHub:#14] Supported nil as single value. [Reported by n3llyb0y] * [GitHub:#20] Supported ActiveModel::MassAssignmentSecurity. [Reported by mihu] * [GitHub:#24] Supported Ruby 1.9 style Hash syntax in generator. [Patch by ursm] * [GitHub:#25][GitHub:#39] Supported ActiveModel::Dirty. [Patch by mihu][Reported by Ben Langfeld] * [GitHub:#26] Improved speed for dirty. [Patch by mihu] * [GitHub:#28] Improved speed for initialization. [Patch by mihu] * [GitHub:#29] Added .gemspec. [Suggested by mklappstuhl] * [GitHub:#34] Removed an unused method. [Patch by mihu] * [GitHub:#37] Improved will_paginate support. [Patch by Craig White] * [GitHub:#40] Added missing test files to .gemspec. [Reported by Vít Ondruch] * [GitHub:#41] Improved speed for find. [Patch by unixmechanic] * Changed i18n backend to gettext from fast_gettext again. * [GitHub:#42] Fixed a bug that optional second is required for GeneralizedTime. [Reported by masche842] h3. Thanks * sailesh * Alex Tomlins * n3llyb0y * mihu * ursm * Ben Langfeld * mklappstuhl * Craig White * Vít Ondruch * unixmechanic * masche842 h2(#3-1-1). 3.1.1: 2011-11-03 * Supported Rails 3.1.1. * [GitHub:#9] Fixed a typo in document. [warden] * [GitHub:#11] Added persisted?. [bklier] * [GitHub:#16] Supported 4 or more bytes salt for SSHA and SMD5. [Alex Tomlins] h3. Thanks * warden * bklier * Alex Tomlins h2(#3-1-0). 3.1.0: 2011-07-09 * Supported Rails 3.1.0.rc4. [Ryan Tandy, Narihiro Nakamura, Hidetoshi Yoshimoto] * Removed ActiveRecord dependency and added ActiveModel dependency. * Used YARD instead of RDoc as documentation sysytem. h2. 1.2.4: 2011-05-13 * Splited AL-Admin into other repository: https://github.com/activeldap/al-admin * [GitHub:#2] Fixed "path po cound not be found" error by fast_gettext. [rbq] h2. 1.2.3: 2011-04-30 * [#40] Ignored nil value attribute. [christian.pennafort] * [#48] Escaped ":" in filter value. [planetmcd] * Added missing rubygems require. [spoidar] * Used fast_gettext instead of gettext. [Peter Fern] * Supported Rails 2.3.11. [Kris Wehner] * Fixed wrong assertion in test. [Ryan Tandy] h3. Thanks * christian.pennafort * planetmcd * spoidar * Peter Fern * Kris Wehner * Ryan Tandy h2. 1.2.2: 2010-07-04 * Supported ActiveRecord 2.3.8 and Rails 2.3.8. * [#37] Fixed gem dependencies in Rakefile. [zachwily] * Fixed a bug that setting 'false' but 'nil' is returned. [Hideyuki Yasuda] * Supported non-String attribute value as LDIF value. [Matt Mencel] * Worked with a LDAP server that uses 'objectclass' not 'objectClass' as objectClass attribute name. [Tim Hermans] * [#41] Provide SASL-option support, primarily for authzid [Anthony M. Martinez] * [#43] Error with to_xml [ilusi0n.x] * [#44] Accept '0' and '1' as boolean value [projekttabla] * [#27429] Fixed inverted validatation by validate_excluded_classes [Marc Dequènes] * Supported DN attribute value for assosiation replacement. [Jörg Herzinger] h2. 1.2.1: 2009-12-15 * Supported ActiveRecord 2.3.5 and Rails 2.3.5. * Supported GetText 2.1.0 and Locale 2.0.5. * belongs_to(:many) support DN attribute. * [#31] ActiveLdap::Base#attributes returns data that reflects schema definition. [Alexey.Chebotar] * blocks DN attribute change by mass assignment with :id => .... * [#35] fix has_many association is broken. [culturespy] * Supported nested attribute options. [Hideyuki Yasuda] h2. 1.2.0: 2009-09-22 * Supported ActiveRecord 2.3.4 and Rails 2.3.4. * [IMCOMPATIBLE] [#23932] Inconsistant DN handling in object attributes [Marc Dequènes] (ActiveLdap::Base#dn and ActiveLdap::Base#base return ActiveLdap::DN not String) * [#26824] support operational attributes detection [Marc Dequènes] (added ActiveLdap::Schema::Attribute#directory_operation?) * [#27] Error saving an ActiveLDAP user [brad@lucky-dip.net] * [#29] Raised on modify_rdn_entry when rdn already exists [Alexey.Chebotar] * Added ActiveLdap::DN.parent. * Supported renaming an entry. Renaming other DTI is only supported by JNDI backend. h2. 1.1.0: 2009-07-18 * Improved tutorial. [Kazuaki Takase] * Improvements: ** API: *** [#26] Supported to_xml for associations. [achemze] *** ActiveLdap::Base.delete_all(filter=nil, options={}) -> ActiveLdap::Base.delete_all(filter_or_options={}). Sure, old method signature is also still supported. *** belongs_to(:many) with :foreign_key is deprecated. Use :primary_key instead of :foreign_key. [Kazuaki Takase] *** Means of has_many's :primary_key and :foreign_key are inverted. [Kazuaki Takase] *** [experimental] Added ldap_field ActionView helper to generate form fileds for a LDAP entry. ** Suppressed needless attributes updating. * Dependencies: ** Re-supported GetText. ** ActiveRecord 2.3.2 is only supported. h2. 1.0.9 * Added documents in Japanese. [Kazuaki Takase] * Supported Ruby 1.9.1. ** [#20] [Ruby 1.9 Support] :: Running Tests [Alexey.Chebotar] * Supported Rails 2.3.2. ** [#18] [Rails 2.3 Support] :: Running WEBrick Hangs [Alexey.Chebotar] * Bug fixes: ** Fixed blank values detection. [David Morton] ** [#22] Ruby 1.8.6 p287 :: Undefined methods [Alexey.Chebotar] ** Fixed gem loading. [Tiago Fernandes] ** Fixed DN change via #base=. [David Morton] ** Fixed infinite retry on timeout. ** Fixed needless reconnection. * API improvements: ** Removed needless instance methods: #prefix=, #dn_attribute=, #sort_by=, #order=, #required_classes=, #recommended_classes= and #excluded_classes. [David Morton] ** Removed obsolete scafoold_al generator. ** Reduced default :retry_limit. ** Supported association as parameter. [Joe Francis] ** Normalized schema attribute name. [Tim Hermans] ** Suppressed AuthenticationError -> ConnectionError conversion on reconnection. [Kazuaki Takase] ** Added ActiveLdap::Schema#dump. ** ActiveLdap::Base.establish_connection -> ActiveLdap::Base.setup_connection. ** Supported ActiveLdap::Base.find(:last). ** Added convenient methods: *** ActiveLdap::Base.first *** ActiveLdap::Base.last *** ActiveLdap::Base.all h2. 1.0.2 * Removed Base64 module use. * Improved LDIF parser. * Improved scheme parser. * Supported Base64 in XML serialization. * Supported TLS options. * Supported ActiveRecord 2.2.2. * Supported Ruby on Rails 2.2.2. * Used rails/init.rb and rails_generators/ directory structure convention for Rails and gem. rails/ directory will be removed after 1.0.2 is released. * AL-Admin migrated to Ruby on Rails 2.2.2 form 2.0.2. * Improved ActiveDirectory integration. * Accepted :class_name for belong_to and has_many option. * Improved default port guess. * Bug fixes: ** [#4] ModifyRecord#load doesn't operate atomic. [gwarf12] ** [#5] to_xml supports :except option. [baptiste.grenier] ** [#6] to_xml uses ActiveResource format. [baptiste.grenier] ** Out of ranged GeneralizedTime uses Time.at(0) as fallback value. [Richard Nicholas] ** ActiveLdap::Base#to_s uses #to_ldif. [Kazuhiro NISHIYAMA] ** Fixed excess prefix extraction. [Grzegorz Marszałek] ** Skiped read only attribute validation. [しまさわらさん] ** Treated "" as empty value. [Ted Lepich] ** [#9][#16] Reduced raising when DN value is invalid. [danger1986][Alexey.Chebotar] ** [#10][#12] Fixed needless ',' is appeared. [michael.j.konopka] ** [#11] Required missing 'active_ldap/user_password'. [michael.j.konopka] ** [#13] Returned entries if has_many :wrap has nonexistent entry. [ingersoll] ** [#15] Fixed type error on computing DN. [ery.lee] ** ">=" filter operator doesn't work. [id:dicdak] ** [#17] ActiveLdap::Base.create doesn't raise exception. [Alexey.Chebotar] h2. 1.0.1 * Fixed GetText integration. * Fixed ActiveLdap::Base.find with ActiveLdap::DN. (Reported by Jeremy Pruitt) * Fixed associated bugs. (Reported by CultureSpy) * Supported ActiveLdap::Base#attribute_present? with nonexistence attribute. (Reported by Matt Mencel) * Added ActiveLdap::Base#.to_ldif_record. * Improved inspect. * Supported ActiveSupport 2.1.0. h2. 1.0.0 * Fixed GSSAPI auth failure. [#18764] (Reported by Lennon Day-Reynolds) * Supported Symbol as :dn_attribute_value. [#18921] (Requested by Nobody) * Improved DN attribute detection. (Reported by Iain Pople) * Avoided unnecesally modify operation. (Reported by Tilo) h2. 0.10.0 * Implemented LDIF parser. * Improved validation: ** Added some validations. ** Fixed SINGLE-VALUE validation. [#17763] (Reported by Naoto Morishima) * Supported JNDI as backend. * Improved auto reconnection. * Supported Rails 2.0.2. * Improved performance. (4x) * [API CHANGE]: removed "'binary' =>" from getter result.
  !!!plain
  e.g.:
    before:
        user.user_certificate # => {"binary" => "..."}
       now:
        user.user_certificate # => "..."
  
* Added :excluded_classed ldap_mapping option. * Logged operation time used for LDAP operation. * Improved API: ** Accepted non String value for find(:value => XXX). (Suggested by Marc Dequèn) ** Accepted DN as ActiveLdap::Base.new(XXX). (Reported by Jeremy Pruitt) ** Treated empty password for smiple bind as anonymous bind. (Suggested by Bodaniel Jeans) ** Ensured adding "objectClass" for find's :attribute value. [#16946] (Suggested by Nobody) ** Fixed a GeneralizedTime type casting bug. (Reported by Bodaniel Jeanes) ** Supported :base and :prefix search/find option value escaping. (Suggested by David Morton) h2. 0.9.0 * Improved DN handling. * Supported attribute value validation by LDAP schema. * Changed RubyGems name: ruby-activeldap -> activeldap. * Removed Log4r dependency. * Supported lazy connection establishing. ** [API CHANGE]: establish_connection doesn't connect LDAP server. * [API CHANGE]: Removed ActiveLdap::Base#establish_connection. * Added ActiveLdap::Base#bind. (use this instead of #establish_connection) * Supported implicit acts_as_tree. * [API CHANGE]: Supported type casting. * Supported :uri option in configuration. * Improved Rails integration: ** Followed Rails 2.0 changes. ** AL-Admin: *** Supported lang parameter in URL. *** Improved design a bit. (Please someone help us!) *** Supported schema inspection. *** Supported objectClass modifiation. ** Rails plugin: *** Added ActiveLdap::VERSION check. *** Added model_active_ldap generator. *** Renamed scaffold_al generator to scaffold_active_ldap. h2. 0.8.3 * Added AL-Admin Sample Rails app * Added Ruby-GetText-Package support * Added a Rails plugin * Improved schema handling * Improved performance * Many bug fixes h2. 0.8.2 * Added Net::LDAP support! ** supported SASL Digest-MD5 authentication with Net::LDAP. * improved LDAP server support: ** improved Sun DS support. ** improved ActiveDirectory support. Thanks to Ernie Miller! ** improved Fedora-DS support. Thanks to Daniel Pfile! * improved existing functions: ** improved DN handling. Thanks to James Hughes! ** improved SASL bind. ** improved old API check. ** improved schema handling. Thanks to Christoph Lipp! ** improved filter notification. * updated documents: ** updated Rails realted documenation. Thanks to James Hughes! ** updated documentation for the changes between 0.7.1 and 0.8.0. Thanks to Buzz Chopra! * added new features: ** added scaffold_al generator for Rails. ** added required_classes to default filter value. Thanks to Jeff Hall! ** added :recommended_classes option to ldap_mapping. ** added :sort_by and :order options to find. ** added ActiveLdap::Base#to_param for ActionController. * fixed some bugs: ** fixed rake install/uninstall. ** fixed typos. Thanks to Nobody! ** fixed required_classes initialization. Thanks to James Hughes! h2. 0.8.1 * used Dependencies.load_paths. * check whether attribute name is available or not. * added test for find(:first, :attribute => 'xxx', :value => 'yyy'). * supported ActiveSupport 1.4.0. * make the dual licensing of ruby-activeldap clear in the README. * followed edge Rails: don't use Reloadable::Subclasses if doesn't need. * added examples/. * removed debug code. * normalized attribute name to support wrong attribute names in MUST/MAY. * supported getting dn value by Base#[]. * test/test_userls.rb: followed userls changes. * update the doc href. * provide a dumb example of how to use the old association(return_objects) style API with the new awesome API. * followed new API. * removed a finished task: support Reloadable::Subclasses. h2. 0.8.0 * Makefile/gemspec system replaced with Rakefile + Hoe * Bugfix: Allow base to be empty * Add support for Date, DateTime, and Time objects (patch from Patrick Cole) * Add support for a :filter argument to override the default attr=val LDAP search filter in find_all() and find() (patch from Patrick Cole) * Add Base#update_attributes(hash) method which does bulk updates to attributes (patch from Patrick Cole) and saves immediately * API CHANGE: #attributes now returns a Hash of attribute_name => clone(attribute_val) * API CHANGE: #attribute_names now returns an alphabetically sorted list of attribute names * API CHANGE; * Added attributes=() as the implementation for update_attributes(hash) (without autosave) * API TRANSITION: Base#write is now deprecated. Please use Base#save * API TRANSITION: Added SaveError exception (which is a subclass of WriteError for now) * API TRANSITION: Base.connect() is now deprecated. Please use Base.establish_connection() * API TRANSITION: Base.close() is now deprecated. Please use Base.remove_connection() * API TRANSITION: :bind_format and :user of Base.establish_connection() are now deprecated. Please use :bind_dn * Added update_attribute(name, value) to update one attribute and save immediately * #delete -> #destroy * Base.destroy_all * Base.delete(id) & Base.delete_all(filter) * add Base.exists?(dnattr_val) * attr_protected * Base.update(dnattr_val, attributes_hash) - instantiate, update, save, return * Base.update_all(updates_hash, filter) * attribute_present?(attribute) - if not empty/nil * has_attribute?(attr_name) - if in hash * reload() (refetch from LDAP) * make save() return false on fail * make save!() raise EntryNotSaved exception * to_xml() * clear_active_connections!() -- Conn per class ** make @@active_connections and name them by * base_class() (just return the ancestor) * Separate ObjectClass changes to live in ActiveLDAP::ObjectClass ** add_objectclass ** remove_objectclass ** replace_objectclass ** disallow direct objectclass access? * support ActiveRecord::Validations. * support ActiveRecord::Callbacks. * rename to ActiveLdap from ActiveLDAP to integrate RoR easily and enforce many API changes. h2. 0.7.4 * Bugfix: do not base LDAP::PrettyError on RuntimeError due to rescue evaluation. * Bugfix: :return_objects was overriding :objects in find and find_all * Rollup exception code into smaller space reusing similar code. h2. 0.7.3 * Made has_many and belongs_to use :return_objects value * Force generation of LDAP constants on import - currently broken h2. 0.7.2 * Stopped overriding Conn.schema in ldap/schema - now use schema2 * Fix attributes being deleted when changing between objectclasses with shared attributes * Added schema attribute case insensitivity * Added case insensitivity to the attribute methods. * Added LDAP scope override support to ldap_mapping via :scope argument. (ldap_mapping :scope => LDAP::LDAP_SCOPE_SUBTREE, ...) * Fixed the bug where Klass.find() return nil (default arg for find/find_all now '*') * Added :return_objects to Base.connect()/configuration.rb -- When true, sets the default behavior in Base.find/find_all to return objects instead of just the dnattr string. * Hid away several exposed private class methods (do_bind, etc) * Undefined dnattr for a class now raises a ConfigurationError * Centralized all connection management code where possible * Added Base.can_reconnect? which returns true if never connected or below the :retries limit * Added block support to Base.connection to ensure "safe" connection usage. This is not just for internal library use. If you need to do something fancy with the connection object, use Base.connection do |conn| ... * Fixed object instantiation in Base#initialize when using full DNs * Added :parent_class option to ldap_mapping which allows for object.parent() to return an instantiated object using the parent DN. (ldap_mapping :parent_class => String, ...) * Fixed reconnect bug in Base#initialize (didn't respect infinite retries) * Added(*) :timeout argument to allow timeouts on hanging LDAP connections * Added(*) :retry_on_timeout boolean option to allow disabling retries on timeouts * Added TimeoutError * Added(*) a forking timeout using SIGALRM to interrupt handling. * (*) Only works when RUBY_PLATFORM has "linux" in it h2. 0.7.1 * Fix broken -W0 arg in activeldap.rb * attribute_method=: '' and nil converted to ldap-pleasing [] values * Added checks in write and search for connection down (to reconnect) * Fixed broken idea of LDAP::err2string exceptions. Instead took errcodes from ldap.c in Ruby/LDAP. h2. 0.7.0 * ConnectionError thrown from #initialize when there is no connection and retry limit was exceeded * ConnectionError thrown when retries exceeded when no connection was created * Separated connection types: SSL, TLS, and plain using :method * Localized reconnect logic into Base.reconnect(force=false) * Fixed password_block evaluation bug in do_bind() which broke SIMPLE re-binds and broke reconnect * Add support for config[:sasl_quiet] in Base.connect * (Delayed a case sensitivity patch for object classes and attributes due to weird errors) * Add :retry_wait to Base.connect to determine the timeout before retrying a connection * Fixed ActiveLDAP::Base.create_object() - classes were enclosed in quotes * Added :ldap_scope Base.connect() argument to allow risk-seeking users to change the LDAP scope to something other than ONELEVEL. * Cleaned up Configuration.rb to supply all default values for ActiveLDAP::Base.connect() and to use a constant instead of overriding class variables for no good reason. * Added scrubbing for :base argument into Base.connect() to make sure a ' doesn't get evaluated. * Refactored Base.connect(). It is now much cleaner and easier to follow. * Moved schema retrieval to after bind in case a server requires privileges to access it. * Reworked the bind process to be a little prettier. A lot of work to do here still. * Added LDAP::err2exception(errno) which is the groundwork of a coming overhaul in user friendly error handling. * Added support for Base::connect(.., :password => String, ...) to avoid stupid Proc.new {'foo'} crap * Add :store_password option. When this is set, :password is not cleared and :password_block is not re-evaluated on each rebind. h2. 0.6.0 * Disallow blank DN attribute values on initialization * Fix bug reported by Maik Schmidt regarding object creation * Added error checking to disallow DN attribute value changes * Added AttributeAssignmentError (for above) * Import() and initialize() no longer call attribute_method=() * Added error condition if connection fails inside initialize() * Changes examples and tests to use "dc=localdomain" * has_many() entries no longer return nil when empty h2. 0.5.9 * Change default base to dc=localdomain (as per Debian default). * schema2.rb:attr() now returns [] instead of '' when empty. * Lookup of new objects does not put dnattr()=value into the Base on lookup. * Scope is now use ONELEVEL instead of SUBTREE as it broke object boundaries. * Fixed @max_retries misuse. * Added do_connect retries. * Fixed find and find_all for the case - find_all('*'). * Fixed broken creation of objects from anonymous classes. * Fixed broken use of ldap_mapping with anonymous classes. h2. 0.5.8: Bugfix galore * Allow nil "prefix" * Fixed the dup bug with Anonymous patch. * (maybe) Fixed stale connection problems by attempting reconn/bind. * Hiding redefine warnings (for now) h2. 0.5.7 * Fixed the @data.default = [] bug that daniel@nightrunner.com pointed out (and partially patched). h2. 0.5.6 * Added support for foreign_key => 'dn' in has_many. h2. 0.5.5 * Remove @@logger.debug entries during build * Building -debug and regular gems and tarballs h2. 0.5.4 * Added Base#import to streamline the Base.find and Base.find_all methods ** Speeds up find and find_all by not accessing LDAP multiple times for data we already have. * Added tests/benchmark which is a slightly modified version of excellent benchmarking code contributed by Ollivier Robert . h2. 0.5.3 * Changed attribute_method to send in associations ** fixes belongs_to (with local_kay) and inheritance around that h2. 0.5.2 * Make sure values are .dup'd when they come from LDAP h2. 0.5.1 * Changed Schema2#class_attributes to return @{:must => [], :may => []}@ * Fixed Base#must and Base#may to return with full SUPerclass requirements h2. 0.5.0 * API CHANGE (as with all 0.x.0 changes) (towards ActiveRecord duck typing) ** Base#ldapattribute now always returns an array ** Base#ldapattribute(true) now returns a dup of an array, string, etc when appropriate (old default) - This is just for convenience ** Base#ldapattribute returns the stored value, not just a .dup ** Associations methods return objects by default instead of just names. Group.new('foo').members(false) will return names only. ** Base.connect returns true as one might expect * Value validation and changing (binary, etc) occur prior to write, and not immediately on attribute_method=(value). * Attribute method validity is now determined /on-the-fly/. * Default log level set to OFF speeds up 'speedtest' by 3 seconds! (counters last point which added some slowness :) * Added Schema2#class_attributes which caches and fully supertype expands attribute lists. * Integrated Schema2#class_attributes with apply_objectclass which automagically does SUP traversal and automagically updates available methods on calls to #attributes, #method_missing, #validate, and #write * Added 'attributes' to 'methods' allowing for irb autocompletion and other normal rubyisms * Moved almost all validation to Base#validate to avoid unexpected exceptions being raised in seemingly unrelated method calls. This means that invalid objectClasses may be specified. This will only be caught on #write or a pre-emptive #validate. This goes for all attribute errors though. This also makes it possible to "break" objects by removing the 'top' objectclass and therefore the #objectClass method... h2. 0.4.4 * Fixed binary subtype forcing: ** was setting data as subtype ;binary even when not required * Added first set of unit tests. ** These will be cleaned up in later releases as more tests are added. * Fixed subtype clobber non-subtype (unittest!) ** cn and cn;lang-blah: the last loaded won * Fixed multivalued subtypes from being shoved into a string (unittest!) ** an error with attribute_input_value h2. 0.4.3 * Fixed write (add) bugs introduced with last change ** only bug fixes until unittests are in place h2. 0.4.2 * Added ruby-activeldap.gemspec * Integrated building a gem of 'ruby-activeldap' into Makefile.package * Added attr parsing cache to speed up repetitive calls: approx 13x speedup ** 100 usermod-binary-add calls
   !!!plain
   Without attr parsing cache:
     real    13m53.129s
     user    13m11.350s
     sys     0m7.030s
   With attr parsing cache:
     real    1m0.416s
     user    0m28.390s
     sys     0m2.380s
   
h2. 0.4.1: * Schema2 was not correctly parsing objectClass entries. ** This is fixed for now but must be revisited. h2. 0.4.0 * Added #(arrays) argument which when true always returns arrays. e.g.
  !!!plain
  irb> user.cn(true)
  => ['My Common Name']
  
This makes things easier for larger programming tasks. * Added subtype support: ** Uses Hash objects to specify the subtype e.g. @user.userCertificate = {'binary' => File.read('mycert.der')}@ ** Added recursive type enforcement along with the subtype handling ** This required overhauling the #write method. *** Please report any problems ASAP! :^) * Added automagic binary support ** subtype wrapping done automatically ** relies on X-NOT-HUMAN-READABLE flag * Added LDAP::Schema2 which is an extension of Ruby/LDAP::Schema ** made Schema#attr generic for easy type dereferencing * Updated rdoc in activeldap.rb * Updated examples (poorly) to reflect new functionality * Added several private helper functions h2. 0.3.6 * Fixed dn attribute value extraction on find and find_all ** these may have grabbed the wrong value if a DN attr has multiple values. * Fixed Base.search to return all values as arrays and update multivalued ones correctly * Lowered the amount of default logging to FATAL only h2. 0.3.5 * Moved to rubyforge.org! h2. 0.3.4 * Changed license to Ruby's h2. 0.3.3 * Changed Base.search to return an array instead of a hash of hashes * Change Base.search to take in a hash as its arguments h2. 0.3.2 * Bug fix - fixed support for module'd extension classes (again!) h2. 0.3.1 * Updated the documentation * Fixed ignoring of attrs argument in Base.search * Fixed mistake in groupls (using dnattr directly) * Fixed a mistake with overzealous dup'ing h2. 0.3.0 * MORE API CHANGES (configuration.rb, etc) * Major overhaul to the internals! ** removed @@BLAH[@klass] in lieu of defining class methods which contain the required values. This allows for clean inheritance of Base subclasses! Whew! ** Added @@config to store the options currently in use after a Base.connect ** Now cache passwords for doing reconnects ** dnattr now accessible to the outside as a class method only * Added Base.search to wrap normal LDAP search for convenience. ** This returns a hash of hashes with the results indexed first by full dn, then by attribute. h2. 0.2.0 * API CHANGES: ** Extension classes must be defined using map_to_ldap instead of setting random values in initialize ** Base#find is now Base.find_all and is a class method ** Base.find returns the first match a la Array#find ** force_reload is gone in belongs_to and has_many created methods ** hiding Base.new, Base.find, and Base.find_all from direct access * added uniq to setting objectClass to avoid stupid errors * fixed new object creation bug where attributes were added before the objectclass resulting in a violation (Base#write) * fixed attribute dereferencing in Base#write * fixed bug with .dup on Fixnums * methods created by has_many/belongs_to and find and find_all now take an optional argument dnattr_only which will return the value of dnattr for each result instead of a full object. * Base.connection=(conn) added for multiplexing connections * Added a manual to activeldap.rb which covers most usage of Ruby/ActiveLDAP * Base.connect(:try_sasl => true) should now work with GSSAPI if you are using OpenLDAP >= 2.1.29 h2. 0.1.8 * .dup all returned attribute values to avoid weirdness * .dup all assigned values to avoid weirdness * Changed default configuration.rb to use example.com h2. 0.1.7 * Added support for non-unique DN attributes * Added authoritative DN retrieval with 'object.dn' h2. 0.1.6 * Added Base.close method for clearing the existing connection (despite Ruby/LDAP's lack of .close) h2. 0.1.5 * Fixed incorrect usage of @klass in .find (should .find be a class method?) h2. 0.1.4 * Change WARN to INFO in associations.rb for has_many h2. 0.1.3 * Fixed class name mangling * Added support for classes to take DNs as the initialization value h2. 0.1.2 * Patch from Dick Davies: Try SSL before TLS * Log4r support * Better packaging (automated) * Work-around for SSL stupidity ** SSLConn doesn't check if the port it connected to is really using SSL! h2. 0.1.1 * Dynamic table class creation * SASL/GSSAPI disabled by default - doesn't work consistently h2. 0.1.0 * Added foreign_key to has_many * Added local_key to belongs_to * Added primary_members to Group example * Added "nil" filtering to has_many * Packaged up with setup.rb * Added RDocs and better comments h2. 0.0.9 * Separated extension classes from ActiveLDAP module * Cleaned up examples with new requires h2. 0.0.8 * Added user and group scripting examples ** usermod, userls, useradd, userdel ** groupmod, groupls h2. 0.0.7 * Cleaner authentication loop: ** SASL (GSSAPI only), simple, anonymous * Added allow_anonymous option added (default: false) h2. 0.0.6 * Write support cleaned up * Exception classes added h2. 0.0.5 * LDAP write support added h2. 0.0.4 * MUST and MAY data validation against schema using objectClasses h2. 0.0.3 * LDAP attributes alias resolution and data mapping h2. 0.0.2 * Associations: has_many and belongs_to Class methods added for Base h2. 0.0.1 * Extension approach in place with example User and Group classes h2. 0.0.0 * Basic LDAP read support in place with hard-coded OUs activeldap-5.2.4/Gemfile0000644000004100000410000000027513464071751015175 0ustar www-datawww-data# -*- ruby -*- source "http://rubygems.org" gemspec group :test do gem "net-ldap" platforms :mri do gem "ruby-ldap" end platforms :jruby do gem "jruby-openssl" end end activeldap-5.2.4/README.textile0000644000004100000410000000773713464071751016251 0ustar www-datawww-datah1. ActiveLdap A ruby library for object-oriented LDAP interface. * Copyright (C) 2004-2006 Will Drewry __ * Copyright (C) 2006-2013 Kouhei Sutou __ h2. Description 'ActiveLdap' is a ruby library which provides a clean objected oriented interface to LDAP library. It was inspired by ActiveRecord. This is not nearly as clean or as flexible as ActiveRecord, but it is still trivial to define new objects and manipulate them with minimal difficulty. For example and usage - read the "document":http://activeldap.github.io/. h2. Prerequisites - Ruby intepreter := One of them: * "Ruby":http://www.ruby-lang.org (1.9.3, 2.0.x, 2.1.x, 2.2.x, 2.3.0) * "JRuby":http://www.jruby.org/ See the above links for installation. =: - LDAP client := JRuby doesn't need to install new library because JRuby has builtin LDAP support. Ruby users need one of them: * "Ruby/LDAP":http://ruby-ldap.sourceforge.net/ * "Net::LDAP":http://rubyldap.com/ See the above links for installation. =: - ActiveModel := A toolkit for building modeling frameworks like Active Record and Active Resource. =: h2. Notes * Only GSSAPI SASL support exists due to Ruby/LDAP limitations h2. Rails See "Rails":file.rails.html ("doc/text/rails.textile":doc/text/rails.textile in the repository and on GitHub) page for Rails integration. h2. Licence This program is free software; you can redistribute it and/or modify it. It is dual licensed under Ruby's license and under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Please see the file LICENSE for the terms of the licence. h2. Thanks This list may not be correct. If you notice mistakes of this list, please point out. * Dick Davies * Nathan Kinder * Patrick Cole * Google Inc. * Nobody: Bug reports and API improveent ideas. * James Hughes: Bug reports and advices and documentations. * Buzz Chopra: Documentations. * Christoph Lipp: ** Bug reports. ** Tell us character escape syntax. * Jeff Hall: Bug reports. * Ernie Miller: Bug reports and advices. * Daniel Pfile: Patches. * Jacob Wilkins: Bug reports. * Ace Suares: ** Bug reports. ** Nederlands translations. * Iain Pople: Bug reports and API improvement ideas. * Kevin McCarthy: Patches. * Perry Smith: Patches, bug reports and indications. * Marc Dequènes: API suggestions. * Jeremy Pruitt: Bug reports. * Bodaniel Jeanes: ** A suggestion for behavior on simple bind with empty password. ** Bug reports. * Naoto Morishima: Bug reports. * David Morton: ** An API improvement idea. ** Bug reports. * Lennon Day-Reynolds: Bug reports. * Tilo: A bug report. * Matt Mencel: Bug reports. * CultureSpy: ** Bug reports. ** Bug fixes. * gwarf12: A bug report. * Baptiste Grenier: API improvement ideas. * Richard 3 Nicholas: API improvement ideas. * Kazuhiro NISHIYAMA: A bug report. * Grzegorz Marszałek: A bug report. * しまさわらさん: A suggesetion. * Ted Lepich: A suggestion. * danger1986: A suggestion. * michael.j.konopka: Bug reports. * ingersoll: A suggestion. * Alexey.Chebotar: Bug reports. * ery.lee: A bug report. * id:dicdak: A bug report. * Raiko Mitsu: A bug report. * Kazuaki Takase: Documents in Japanese. * Tim Hermans: A bug report. * Joe Francis: A suggestion. * Tiago Fernandes: Bug reports. * achemze: A suggestion. * George Montana Harkin: A suggestion. * Marc Dequènes: Bug reports. * brad@lucky-dip.net: A bug report. * Hideyuki Yasuda: Bug reports. * zachwily: A bug report. * syrius.ml@no-log.org: A bug report. * Tim Hermans: A bug report. * Anthony M. Martinez: Helped SASL options support * ilusi0n.x: A bug report. * projekttabla: A suggestion. * christian.pennaforte: A bug report. * planetmcd: A bug report. * spoidar: Rails 3 support. * Kris Wehner: Rails 2.3.8 support. * Ryan Tandy: ** A test bug fix. ** Rails 3 support. * rbq: A bug report. * Narihiro Nakamura: Rails 3 support. * Hidetoshi Yoshimoto: Rails 3 support. * warden: A bug report. * bklier: A bug fix. * Craig White: Bug reports. activeldap-5.2.4/po/0000755000004100000410000000000013464071751014314 5ustar www-datawww-dataactiveldap-5.2.4/po/ja/0000755000004100000410000000000013464071751014706 5ustar www-datawww-dataactiveldap-5.2.4/po/ja/active-ldap.po0000644000004100000410000033373113464071751017451 0ustar www-datawww-data# Japanese translations for ActiveLdap. # Copyright (C) 2007-2009 Kouhei Sutou # This file is distributed under the same license as the ActiveLdap package. # Kouhei Sutou , 2007. # msgid "" msgstr "" "Project-Id-Version: Ruby/ActiveLdap 1.1.1\n" "POT-Creation-Date: 2009-08-04 23:26+0900\n" "PO-Revision-Date: 2016-05-13 21:53+0900\n" "Last-Translator: Kouhei Sutou \n" "Language-Team: Japanese\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: -:- msgid "LDAP|Attribute|aRecord" msgstr "Aレコード(aRecord)" #: -:- msgid "LDAP|Attribute|aliasedEntryName" msgstr "別名エントリの名前(aliasedEntryName)" #: -:- msgid "LDAP|Attribute|aliasedObjectName" msgstr "別名オブジェクトの名前(aliasedObjectName)" #: -:- msgid "LDAP|Attribute|altServer" msgstr "代替サーバ(altServer)" #: -:- msgid "LDAP|Attribute|associatedDomain" msgstr "関連したドメイン(associatedDomain)" #: -:- msgid "LDAP|Attribute|associatedName" msgstr "関連した名前(associatedName)" #: -:- msgid "LDAP|Attribute|attributeTypes" msgstr "属性種別(attributeTypes)" #: -:- msgid "LDAP|Attribute|audio" msgstr "音声(audio)" #: -:- msgid "LDAP|Attribute|authorityRevocationList" msgstr "失効証明書一覧(authorityRevocationList)" #: -:- msgid "LDAP|Attribute|bootFile" msgstr "起動イメージファイル(bootFile)" #: -:- msgid "LDAP|Attribute|bootParameter" msgstr "起動パラメタ(bootParameter)" #: -:- msgid "LDAP|Attribute|buildingName" msgstr "建物名(buildingName)" #: -:- msgid "LDAP|Attribute|businessCategory" msgstr "業種(businessCategory)" #: -:- msgid "LDAP|Attribute|c" msgstr "国コード(c)" #: -:- msgid "LDAP|Attribute|cACertificate" msgstr "CA証明書(cACertificate)" #: -:- msgid "LDAP|Attribute|cNAMERecord" msgstr "CNAMEレコード(cNAMERecord)" #: -:- msgid "LDAP|Attribute|carLicense" msgstr "運転免許(carLicense)" #: -:- msgid "LDAP|Attribute|certificateRevocationList" msgstr "失効証明書一覧(certificateRevocationList)" #: -:- msgid "LDAP|Attribute|cn" msgstr "共通名(cn)" #: -:- msgid "LDAP|Attribute|co" msgstr "国名(co)" #: -:- msgid "LDAP|Attribute|commonName" msgstr "共通名(commonName)" #: -:- msgid "LDAP|Attribute|countryName" msgstr "国名(countryName)" #: -:- msgid "LDAP|Attribute|createTimestamp" msgstr "作成時刻(createTimestamp)" #: -:- msgid "LDAP|Attribute|creatorsName" msgstr "作成者名(creatorsName)" #: -:- msgid "LDAP|Attribute|crossCertificatePair" msgstr "相互認証組(crossCertificatePair)" #: -:- msgid "LDAP|Attribute|dITRedirect" msgstr "DITリダイレクト先(dITRedirect)" #: -:- msgid "LDAP|Attribute|dSAQuality" msgstr "DSA品質(dSAQuality)" #: -:- msgid "LDAP|Attribute|dc" msgstr "ドメイン要素(dc)" #: -:- msgid "LDAP|Attribute|deltaRevocationList" msgstr "差分失効一覧(deltaRevocationList)" #: -:- msgid "LDAP|Attribute|departmentNumber" msgstr "部門番号(departmentNumber)" #: -:- msgid "LDAP|Attribute|description" msgstr "説明(description)" #: -:- msgid "LDAP|Attribute|destinationIndicator" msgstr "行き先表示(destinationIndicator)" #: -:- msgid "LDAP|Attribute|displayName" msgstr "表示名(displayName)" #: -:- msgid "LDAP|Attribute|distinguishedName" msgstr "識別名(distinguishedName)" #: -:- msgid "LDAP|Attribute|dmdName" msgstr "ディレクトリ管理ドメイン名(dmdName)" #: -:- msgid "LDAP|Attribute|dnQualifier" msgstr "DN限定詞(dnQualifier)" #: -:- msgid "LDAP|Attribute|documentAuthor" msgstr "文書作成者(documentAuthor)" #: -:- msgid "LDAP|Attribute|documentIdentifier" msgstr "文書識別子(documentIdentifier)" #: -:- msgid "LDAP|Attribute|documentLocation" msgstr "文書位置(documentLocation)" #: -:- msgid "LDAP|Attribute|documentPublisher" msgstr "文書発行者(documentPublisher)" #: -:- msgid "LDAP|Attribute|documentTitle" msgstr "文書タイトル(documentTitle)" #: -:- msgid "LDAP|Attribute|documentVersion" msgstr "文書バージョン(documentVersion)" #: -:- msgid "LDAP|Attribute|domainComponent" msgstr "ドメイン要素(domainComponent)" #: -:- msgid "LDAP|Attribute|drink" msgstr "飲み物(drink)" #: -:- msgid "LDAP|Attribute|dynamicSubtrees" msgstr "動的なサブツリー(dynamicSubtrees)" #: -:- msgid "LDAP|Attribute|email" msgstr "Eメール(email)" #: -:- msgid "LDAP|Attribute|emailAddress" msgstr "Eメールアドレス(emailAddress)" #: -:- msgid "LDAP|Attribute|employeeNumber" msgstr "従業員番号(employeeNumber)" #: -:- msgid "LDAP|Attribute|employeeType" msgstr "従業員種別(employeeType)" #: -:- msgid "LDAP|Attribute|enhancedSearchGuide" msgstr "拡張検索案内(enhancedSearchGuide)" #: -:- msgid "LDAP|Attribute|entryDN" msgstr "エントリのDN(entryDN)" #: -:- msgid "LDAP|Attribute|entryTtl" msgstr "エントリのTTL(entryTtl)" #: -:- msgid "LDAP|Attribute|entryUUID" msgstr "エントリのUUID(entryUUID)" #: -:- msgid "LDAP|Attribute|facsimileTelephoneNumber" msgstr "FAX番号(facsimileTelephoneNumber)" #: -:- msgid "LDAP|Attribute|favouriteDrink" msgstr "好きな飲み物(favouriteDrink)" #: -:- msgid "LDAP|Attribute|fax" msgstr "FAX(fax)" #: -:- msgid "LDAP|Attribute|friendlyCountryName" msgstr "友好国名(friendlyCountryName)" #: -:- msgid "LDAP|Attribute|gecos" msgstr "GECOS(gecos)" #: -:- msgid "LDAP|Attribute|generationQualifier" msgstr "世代限定詞(generationQualifier)" #: -:- msgid "LDAP|Attribute|gidNumber" msgstr "GID番号(gidNumber)" #: -:- msgid "LDAP|Attribute|givenName" msgstr "名前(givenName)" #: -:- msgid "LDAP|Attribute|gn" msgstr "名前(gn)" #: -:- msgid "LDAP|Attribute|hasSubordinates" msgstr "下位がある(hasSubordinate)" #: -:- msgid "LDAP|Attribute|homeDirectory" msgstr "ホームディレクトリ(homeDirectory)" #: -:- msgid "LDAP|Attribute|homePhone" msgstr "自宅電話(homePhone)" #: -:- msgid "LDAP|Attribute|homePostalAddress" msgstr "自宅郵便番号(homePostalAddress)" #: -:- msgid "LDAP|Attribute|homeTelephoneNumber" msgstr "自宅電話番号(homeTelephoneNumber)" #: -:- msgid "LDAP|Attribute|host" msgstr "ホスト(host)" #: -:- msgid "LDAP|Attribute|houseIdentifier" msgstr "住宅識別子(houseIdentifier)" #: -:- msgid "LDAP|Attribute|info" msgstr "情報(info)" #: -:- msgid "LDAP|Attribute|initials" msgstr "頭文字(initials)" #: -:- msgid "LDAP|Attribute|internationaliSDNNumber" msgstr "国際IDSN番号(internationaliSDNNumber)" #: -:- msgid "LDAP|Attribute|ipHostNumber" msgstr "IP: ホスト番号(ipHostNumber)" #: -:- msgid "LDAP|Attribute|ipNetmaskNumber" msgstr "IP: ネットマスク番号(ipNetmaskNumber)" #: -:- msgid "LDAP|Attribute|ipNetworkNumber" msgstr "IP: ネットワーク番号(ipNetworkNumber)" #: -:- msgid "LDAP|Attribute|ipProtocolNumber" msgstr "IP: プロトコル番号(ipProtocolNumber)" #: -:- msgid "LDAP|Attribute|ipServicePort" msgstr "IP: サービスポート(ipServicePort)" #: -:- msgid "LDAP|Attribute|ipServiceProtocol" msgstr "IP: サービスプロトコル(ipServiceProtocol)" #: -:- msgid "LDAP|Attribute|janetMailbox" msgstr "JANETのメールボックス(janetMailbox)" #: -:- msgid "LDAP|Attribute|jpegPhoto" msgstr "JPEGの写真(jpegPhoto)" #: -:- msgid "LDAP|Attribute|knowledgeInformation" msgstr "知識情報(knowledgeInformation)" #: -:- msgid "LDAP|Attribute|l" msgstr "地域(l)" #: -:- msgid "LDAP|Attribute|labeledURI" msgstr "ラベル付けされたURI(labeledURI)" #: -:- msgid "LDAP|Attribute|ldapSyntaxes" msgstr "LDAP構文(ldapSyntaxes)" #: -:- msgid "LDAP|Attribute|localityName" msgstr "地域名(localityName)" #: -:- msgid "LDAP|Attribute|loginShell" msgstr "ログインシェル(loginShell)" #: -:- msgid "LDAP|Attribute|mDRecord" msgstr "MDレコード(mDRecord)" #: -:- msgid "LDAP|Attribute|mXRecord" msgstr "MXレコード(mXRecord)" #: -:- msgid "LDAP|Attribute|macAddress" msgstr "MACアドレス(macAddress)" #: -:- msgid "LDAP|Attribute|mail" msgstr "メール(mail)" #: -:- msgid "LDAP|Attribute|mailPreferenceOption" msgstr "メール設定オプション(mailPreferenceOption)" #: -:- msgid "LDAP|Attribute|manager" msgstr "管理者(manager)" #: -:- msgid "LDAP|Attribute|matchingRuleUse" msgstr "使用するマッチ規則(matchingRuleUse)" #: -:- msgid "LDAP|Attribute|matchingRules" msgstr "マッチ規則(matchingRules)" #: -:- msgid "LDAP|Attribute|member" msgstr "メンバー(member)" #: -:- msgid "LDAP|Attribute|memberNisNetgroup" msgstr "NIS: メンバーのネットグループ(memberNisNetgroup)" #: -:- msgid "LDAP|Attribute|memberUid" msgstr "メンバーのUID(memberUid)" #: -:- msgid "LDAP|Attribute|mobile" msgstr "携帯電話(mobile)" #: -:- msgid "LDAP|Attribute|mobileTelephoneNumber" msgstr "携帯電話の番号(mobileTelephoneNumber)" #: -:- msgid "LDAP|Attribute|modifiersName" msgstr "変更者名(modifiersName)" #: -:- msgid "LDAP|Attribute|modifyTimestamp" msgstr "変更時刻(modifyTimestamp)" #: -:- msgid "LDAP|Attribute|nSRecord" msgstr "NSレコード(nSRecord)" #: -:- msgid "LDAP|Attribute|name" msgstr "名前(name)" #: -:- msgid "LDAP|Attribute|namingContexts" msgstr "名前付け文脈(namingContexts)" #: -:- msgid "LDAP|Attribute|nisMapEntry" msgstr "NIS: 写像エントリ(nisMapEntry)" #: -:- msgid "LDAP|Attribute|nisMapName" msgstr "NIS: 写像名(nisMapName)" #: -:- msgid "LDAP|Attribute|nisNetgroupTriple" msgstr "NIS: ネットグループトリプル(nisNetgroupTriple)" #: -:- msgid "LDAP|Attribute|o" msgstr "組織(o)" #: -:- msgid "LDAP|Attribute|objectClass" msgstr "オブジェクトクラス(objectClass)" #: -:- msgid "LDAP|Attribute|objectClasses" msgstr "オブジェクトクラス(objectClasses)" #: -:- msgid "LDAP|Attribute|olcAccess" msgstr "OpenLDAP設定: アクセス制御(olcAccess)" #: -:- msgid "LDAP|Attribute|olcAddContentAcl" msgstr "OpenLDAP設定: 追加操作のアクセス制御(olcAddContentAcl)" #: -:- msgid "LDAP|Attribute|olcAllows" msgstr "OpenLDAP設定: 許可(olcAllows)" #: -:- msgid "LDAP|Attribute|olcArgsFile" msgstr "OpenLDAP設定: 引数で指定した設定ファイル(olcArgsFile)" #: -:- msgid "LDAP|Attribute|olcAttributeOptions" msgstr "OpenLDAP設定: 属性オプション(olcAttributeOptions)" #: -:- msgid "LDAP|Attribute|olcAttributeTypes" msgstr "OpenLDAP設定: 属性種別(olcAttributeTypes)" #: -:- msgid "LDAP|Attribute|olcAuthIDRewrite" msgstr "OpenLDAP設定: 認証ID書き換え(olcAuthIDRewrite)" #: -:- msgid "LDAP|Attribute|olcAuthzPolicy" msgstr "OpenLDAP設定: 認証ポリシー(olcAuthzPolicy)" #: -:- msgid "LDAP|Attribute|olcAuthzRegexp" msgstr "OpenLDAP設定: 認証正規表現(olcAuthzRegexp)" #: -:- msgid "LDAP|Attribute|olcBackend" msgstr "OpenLDAP設定: バックエンド(olcBackend)" #: -:- msgid "LDAP|Attribute|olcConcurrency" msgstr "OpenLDAP設定: 同時接続数(olcConcurrency)" #: -:- msgid "LDAP|Attribute|olcConfigDir" msgstr "OpenLDAP設定: 設定ディレクトリ(olcConfigDir)" #: -:- msgid "LDAP|Attribute|olcConfigFile" msgstr "OpenLDAP設定: 設定ファイル(olcConfigFile)" #: -:- msgid "LDAP|Attribute|olcConnMaxPending" msgstr "OpenLDAP設定: 最大接続待ち数(olcConnMaxPending)" #: -:- msgid "LDAP|Attribute|olcConnMaxPendingAuth" msgstr "OpenLDAP設定: 最大認証待ち接続数(olcConnMaxPendingAuth)" #: -:- msgid "LDAP|Attribute|olcDatabase" msgstr "OpenLDAP設定: データベース(olcDatabase)" #: -:- msgid "LDAP|Attribute|olcDbCacheFree" msgstr "OpenLDAP設定: DB: キャッシュ開放量(olcDbCacheFree)" #: -:- msgid "LDAP|Attribute|olcDbCacheSize" msgstr "OpenLDAP設定: DB: キャッシュ量(olcDbCacheSize)" #: -:- msgid "LDAP|Attribute|olcDbCheckpoint" msgstr "OpenLDAP設定: DB: チェックポイント(olcDbCheckpoint)" #: -:- msgid "LDAP|Attribute|olcDbChecksum" msgstr "OpenLDAP設定: DB: チェックサム(olcDbChecksum)" #: -:- msgid "LDAP|Attribute|olcDbConfig" msgstr "OpenLDAP設定: DB: 設定(olcDbConfig)" #: -:- msgid "LDAP|Attribute|olcDbCryptFile" msgstr "OpenLDAP設定: DB: 暗号化鍵の入ったファイル(olcDbCryptFile)" #: -:- msgid "LDAP|Attribute|olcDbCryptKey" msgstr "OpenLDAP設定: DB: 暗号化鍵(olcDbCryptKey)" #: -:- msgid "LDAP|Attribute|olcDbDNcacheSize" msgstr "OpenLDAP設定: DB: DNキャッシュ量(olcDbDNcacheSize)" #: -:- msgid "LDAP|Attribute|olcDbDirectory" msgstr "OpenLDAP設定: DB: ディレクトリ(olcDbDirectory)" #: -:- msgid "LDAP|Attribute|olcDbDirtyRead" msgstr "OpenLDAP設定: DB: 不正読込(olcDbDirtyRead)" #: -:- msgid "LDAP|Attribute|olcDbIDLcacheSize" msgstr "OpenLDAP設定: DB: IDLキャッシュ量(olcDbIDLcacheSize)" #: -:- msgid "LDAP|Attribute|olcDbIndex" msgstr "OpenLDAP設定: DB: 索引(olcDbIndex)" #: -:- msgid "LDAP|Attribute|olcDbLinearIndex" msgstr "OpenLDAP設定: DB: 線形索引(olcDbLinearIndex)" #: -:- msgid "LDAP|Attribute|olcDbLockDetect" msgstr "OpenLDAP設定: DB: ロック検出(olcDbLockDetect)" #: -:- msgid "LDAP|Attribute|olcDbMode" msgstr "OpenLDAP設定: DB: モード(olcDbMode)" #: -:- msgid "LDAP|Attribute|olcDbNoSync" msgstr "OpenLDAP設定: DB: 非同期(olcDbNoSync)" #: -:- msgid "LDAP|Attribute|olcDbPageSize" msgstr "OpenLDAP設定: DB: ページサイズ(olcDbPageSize)" #: -:- msgid "LDAP|Attribute|olcDbSearchStack" msgstr "OpenLDAP設定: DB: 検索スタック(olcDbSearchStack)" #: -:- msgid "LDAP|Attribute|olcDbShmKey" msgstr "OpenLDAP設定: DB: 共有メモリキー(olcDbShmKey)" #: -:- msgid "LDAP|Attribute|olcDefaultSearchBase" msgstr "OpenLDAP設定: デフォルト検索ベース(olcDefaultSearchBase)" #: -:- msgid "LDAP|Attribute|olcDisallows" msgstr "OpenLDAP設定: 拒否(olcDisallows)" #: -:- msgid "LDAP|Attribute|olcDitContentRules" msgstr "OpenLDAP設定: DIT内容規則(olcDitContentRules)" #: -:- msgid "LDAP|Attribute|olcGentleHUP" msgstr "OpenLDAP設定: 穏やかなHUP(olcGentleHUP)" #: -:- msgid "LDAP|Attribute|olcHidden" msgstr "OpenLDAP設定: DBを隠すかどうか(olcHidden)" #: -:- msgid "LDAP|Attribute|olcIdleTimeout" msgstr "OpenLDAP設定: 待ちタイムアウト(olcIdleTimeout)" #: -:- msgid "LDAP|Attribute|olcInclude" msgstr "OpenLDAP設定: 取り込み(olcInclude)" #: -:- msgid "LDAP|Attribute|olcIndexIntLen" msgstr "OpenLDAP設定: 索引の整数長(olcIndexIntLen)" #: -:- msgid "LDAP|Attribute|olcIndexSubstrAnyLen" msgstr "OpenLDAP設定: 索引に使用する部分文字列長(olcIndexSubstrAnyLen)" #: -:- msgid "LDAP|Attribute|olcIndexSubstrAnyStep" msgstr "OpenLDAP設定: 索引検索時に使用する移動幅(olcIndexSubstrAnyStep)" #: -:- msgid "LDAP|Attribute|olcIndexSubstrIfMaxLen" msgstr "OpenLDAP設定: 索引に使用する部分文字列の最大長(olcIndexSubstrIfMaxLen)" #: -:- msgid "LDAP|Attribute|olcIndexSubstrIfMinLen" msgstr "OpenLDAP設定 索引に使用する部分文字列の最小長(olcIndexSubstrIfMinLen)" #: -:- msgid "LDAP|Attribute|olcLastMod" msgstr "OpenLDAP設定: 最終更新情報(olcLastMod)" #: -:- msgid "LDAP|Attribute|olcLdapSyntaxes" msgstr "OpenLDAP設定: LDAP構文(olcLdapSyntaxes)" #: -:- msgid "LDAP|Attribute|olcLimits" msgstr "OpenLDAP設定: 制限(olcLimits)" #: -:- msgid "LDAP|Attribute|olcLocalSSF" msgstr "OpenLDAP設定: ローカルSSF(olcLocalSSF)" #: -:- msgid "LDAP|Attribute|olcLogFile" msgstr "OpenLDAP設定: ログファイル(olcLogFile)" #: -:- msgid "LDAP|Attribute|olcLogLevel" msgstr "OpenLDAP設定: ログレベル(olcLogLevel)" #: -:- msgid "LDAP|Attribute|olcMaxDerefDepth" msgstr "OpenLDAP設定: 最大別名解決深度(olcMaxDerefDepth)" #: -:- msgid "LDAP|Attribute|olcMirrorMode" msgstr "OpenLDAP設定: ミラーモード(olcMirrorMode)" #: -:- msgid "LDAP|Attribute|olcModuleLoad" msgstr "OpenLDAP設定: ロードするモジュール(olcModuleLoad)" #: -:- msgid "LDAP|Attribute|olcModulePath" msgstr "OpenLDAP設定: モジュールの検索パス(olcModulePath)" #: -:- msgid "LDAP|Attribute|olcMonitoring" msgstr "OpenLDAP設定: 監視(olcMonitoring)" #: -:- msgid "LDAP|Attribute|olcObjectClasses" msgstr "OpenLDAP設定: オブジェクトクラス(olcObjectClasses)" #: -:- msgid "LDAP|Attribute|olcObjectIdentifier" msgstr "OpenLDAP設定: オブジェクト識別子(olcObjectIdentifier)" #: -:- msgid "LDAP|Attribute|olcOverlay" msgstr "OpenLDAP設定: オーバーレイ(olcOverlay)" #: -:- msgid "LDAP|Attribute|olcPasswordCryptSaltFormat" msgstr "" "OpenLDAP設定: パスワード暗号化用サルトの書式(olcPasswordCryptSaltFormat)" #: -:- msgid "LDAP|Attribute|olcPasswordHash" msgstr "OpenLDAP設定: パスワードハッシュ(olcPasswordHash)" #: -:- msgid "LDAP|Attribute|olcPidFile" msgstr "OpenLDAP設定: PIDファイル(olcPidFile)" #: -:- msgid "LDAP|Attribute|olcPlugin" msgstr "OpenLDAP設定: プラグイン(olcPlugin)" #: -:- msgid "LDAP|Attribute|olcPluginLogFile" msgstr "OpenLDAP設定: プラグイン: ログファイル(olcPluginLogFile)" #: -:- msgid "LDAP|Attribute|olcReadOnly" msgstr "OpenLDAP設定: 読み込み専用(olcReadOnly)" #: -:- msgid "LDAP|Attribute|olcReferral" msgstr "OpenLDAP設定: 照会(olcReferral)" #: -:- msgid "LDAP|Attribute|olcReplica" msgstr "OpenLDAP設定: 複製(olcReplica)" #: -:- msgid "LDAP|Attribute|olcReplicaArgsFile" msgstr "OpenLDAP設定: 複製: 引数で指定した設定ファイル(olcReplicaArgsFile0" #: -:- msgid "LDAP|Attribute|olcReplicaPidFile" msgstr "OpenLDAP設定: 複製: PIDファイル(olcReplicaPidFile)" #: -:- msgid "LDAP|Attribute|olcReplicationInterval" msgstr "OpenLDAP設定: 複製間隔(olcReplicationInterval)" #: -:- msgid "LDAP|Attribute|olcReplogFile" msgstr "OpenLDAP設定: 複製用ログファイル(olcReplogFile)" #: -:- msgid "LDAP|Attribute|olcRequires" msgstr "OpenLDAP設定: 必須条件(olcRequires)" #: -:- msgid "LDAP|Attribute|olcRestrict" msgstr "OpenLDAP設定: 制限(olcRestrict)" #: -:- msgid "LDAP|Attribute|olcReverseLookup" msgstr "OpenLDAP設定: 逆引き(olcReverseLookup)" #: -:- msgid "LDAP|Attribute|olcRootDN" msgstr "OpenLDAP設定: ルートDN(olcRootDN)" #: -:- msgid "LDAP|Attribute|olcRootDSE" msgstr "OpenLDAP設定: ルートDSE(olcRootDSE)" #: -:- msgid "LDAP|Attribute|olcRootPW" msgstr "OpenLDAP設定: ルートパスワード(olcRootPW)" #: -:- msgid "LDAP|Attribute|olcSaslAuxprops" msgstr "OpenLDAP設定: SASL: 補助プロパティ(olcSaslAuxprops)" #: -:- msgid "LDAP|Attribute|olcSaslHost" msgstr "OpenLDAP設定: SASL: ホスト(olcSaslHost)" #: -:- msgid "LDAP|Attribute|olcSaslRealm" msgstr "OpenLDAP設定: SASL: 領域(olcSaslRealm)" #: -:- msgid "LDAP|Attribute|olcSaslSecProps" msgstr "OpenLDAP設定: SASL: セキュリティプロパティ(olcSaslSecProps)" #: -:- msgid "LDAP|Attribute|olcSchemaDN" msgstr "OpenLDAP設定: スキーマDN(olcSchemaDN)" #: -:- msgid "LDAP|Attribute|olcSecurity" msgstr "OpenLDAP設定: セキュリティ(olcSecurity)" #: -:- msgid "LDAP|Attribute|olcServerID" msgstr "OpenLDAP設定: サーバID(olcServerID)" #: -:- msgid "LDAP|Attribute|olcSizeLimit" msgstr "OpenLDAP設定: サイズ制限(olcSizeLimit)" #: -:- msgid "LDAP|Attribute|olcSockbufMaxIncoming" msgstr "OpenLDAP設定: 匿名接続用最大受信量(olcSockbufMaxIncoming)" #: -:- msgid "LDAP|Attribute|olcSockbufMaxIncomingAuth" msgstr "OpenLDAP設定: 認証接続用最大受信量(olcSockbufMaxIncomingAuth)" #: -:- msgid "LDAP|Attribute|olcSortVals" msgstr "OpenLDAP設定: 並び替えておく値(olcSortVals)" #: -:- msgid "LDAP|Attribute|olcSubordinate" msgstr "OpenLDAP設定: 下位データベース(olcSubordinate)" #: -:- msgid "LDAP|Attribute|olcSuffix" msgstr "OpenLDAP設定: サフィックス(olcSuffix)" #: -:- msgid "LDAP|Attribute|olcSyncrepl" msgstr "OpenLDAP設定: 同期複製(olcSyncrepl)" #: -:- msgid "LDAP|Attribute|olcTLSCACertificateFile" msgstr "OpenLDAP設定: TLS: CA証明書ファイル(olcTLSCACertificateFile)" #: -:- msgid "LDAP|Attribute|olcTLSCACertificatePath" msgstr "OpenLDAP設定: TLS: CA証明書パス(olcTLSCACertificatePath)" #: -:- msgid "LDAP|Attribute|olcTLSCRLCheck" msgstr "OpenLDAP設定: TLS: 失効証明書一覧チェック(olcTLSCRLCheck)" #: -:- msgid "LDAP|Attribute|olcTLSCRLFile" msgstr "OpenLDAP設定: TLS: 失効証明書一覧ファイル(olcTLSCRLFile)" #: -:- msgid "LDAP|Attribute|olcTLSCertificateFile" msgstr "OpenLDAP設定: TLS: 証明書ファイル(olcTLSCertificateFile)" #: -:- msgid "LDAP|Attribute|olcTLSCertificateKeyFile" msgstr "OpenLDAP設定: TLS: 証明書鍵ファイル(olcTLSCertificateKeyFile)" #: -:- msgid "LDAP|Attribute|olcTLSCipherSuite" msgstr "OpenLDAP設定: TLS: 暗号群(olcTLSCipherSuite)" #: -:- msgid "LDAP|Attribute|olcTLSDHParamFile" msgstr "OpenLDAP設定: TLS: DHパラメタファイル(olcTLSDHParamFile)" #: -:- msgid "LDAP|Attribute|olcTLSProtocolMin" msgstr "OpenLDAP設定: TLS: 最小プロトコルバージョン(olcTLSProtocolMin)" #: -:- msgid "LDAP|Attribute|olcTLSRandFile" msgstr "OpenLDAP設定: TLS: ランダムファイル(olcTLSRandFile)" #: -:- msgid "LDAP|Attribute|olcTLSVerifyClient" msgstr "OpenLDAP設定: TLS: クライアント検証(olcTLSVerifyClient)" #: -:- msgid "LDAP|Attribute|olcThreads" msgstr "OpenLDAP設定: 最大スレッド数(olcThreads)" #: -:- msgid "LDAP|Attribute|olcTimeLimit" msgstr "OpenLDAP設定: 時間制限(olcTimeLimit)" #: -:- msgid "LDAP|Attribute|olcToolThreads" msgstr "OpenLDAP設定: ツールモード時の最大スレッド数(olcToolThreads)" #: -:- msgid "LDAP|Attribute|olcUpdateDN" msgstr "OpenLDAP設定: 更新用DN(olcUpdateDN)" #: -:- msgid "LDAP|Attribute|olcUpdateRef" msgstr "OpenLDAP設定: 更新要求時の紹介URL(olcUpdateRef)" #: -:- msgid "LDAP|Attribute|olcWriteTimeout" msgstr "OpenLDAP設定: 書き込みタイムアウト(olcWriteTimeout)" #: -:- msgid "LDAP|Attribute|oncRpcNumber" msgstr "ONC RPC番号(oncRpcNumber)" #: -:- msgid "LDAP|Attribute|organizationName" msgstr "組織名(organizationName)" #: -:- msgid "LDAP|Attribute|organizationalStatus" msgstr "組織状態(organizationalStatus)" #: -:- msgid "LDAP|Attribute|organizationalUnitName" msgstr "組織単位名(organizationalUnitName)" #: -:- msgid "LDAP|Attribute|otherMailbox" msgstr "別のメールボックス(otherMailbox)" #: -:- msgid "LDAP|Attribute|ou" msgstr "組織単位名(ou)" #: -:- msgid "LDAP|Attribute|owner" msgstr "所有者(owner)" #: -:- msgid "LDAP|Attribute|pager" msgstr "ポケベル(pager)" #: -:- msgid "LDAP|Attribute|pagerTelephoneNumber" msgstr "ポケベルの番号(pagerTelephoneNumber)" #: -:- msgid "LDAP|Attribute|personalSignature" msgstr "個人的な署名(personalSignature)" #: -:- msgid "LDAP|Attribute|personalTitle" msgstr "個人的な肩書き(personalTitle)" #: -:- msgid "LDAP|Attribute|photo" msgstr "写真(photo)" #: -:- msgid "LDAP|Attribute|physicalDeliveryOfficeName" msgstr "現物引き渡しオフィス名(physicalDeliveryOfficeName)" #: -:- msgid "LDAP|Attribute|pkcs9email" msgstr "PKCS #9のEメール(pkcs9email)" #: -:- msgid "LDAP|Attribute|postOfficeBox" msgstr "私書箱(postOfficeBox)" #: -:- msgid "LDAP|Attribute|postalAddress" msgstr "郵便の宛先(postalAddress)" #: -:- msgid "LDAP|Attribute|postalCode" msgstr "郵便番号(postalCode)" #: -:- msgid "LDAP|Attribute|preferredDeliveryMethod" msgstr "希望する配達方法(preferredDeliveryMethod)" #: -:- msgid "LDAP|Attribute|preferredLanguage" msgstr "希望する言語(preferredLanguage)" #: -:- msgid "LDAP|Attribute|presentationAddress" msgstr "OSIプレゼンテーションアドレス(presentationAddress)" #: -:- msgid "LDAP|Attribute|protocolInformation" msgstr "プロトコル情報(protocolInformation)" #: -:- msgid "LDAP|Attribute|pseudonym" msgstr "仮名(pseudonym)" #: -:- msgid "LDAP|Attribute|ref" msgstr "参照(ref)" #: -:- msgid "LDAP|Attribute|registeredAddress" msgstr "登録済みアドレス(registeredAddress)" #: -:- msgid "LDAP|Attribute|rfc822Mailbox" msgstr "RFC822メールボックス(rfc822Mailbox)" #: -:- msgid "LDAP|Attribute|roleOccupant" msgstr "居住者の役割(roleOccupant)" #: -:- msgid "LDAP|Attribute|roomNumber" msgstr "部屋番号(roomNumber)" #: -:- msgid "LDAP|Attribute|sOARecord" msgstr "SOAレコード(sOARecord)" #: -:- msgid "LDAP|Attribute|sambaAcctFlags" msgstr "Samba: アカウントフラグ(sambaAcctFlags)" #: -:- msgid "LDAP|Attribute|sambaAlgorithmicRidBase" msgstr "Samba: RID生成アルゴリズム用ベース(sambaAlgorithmicRidBase)" #: -:- msgid "LDAP|Attribute|sambaBadPasswordCount" msgstr "Samba: パスワード失敗回数(sambaBadPasswordCount)" #: -:- msgid "LDAP|Attribute|sambaBadPasswordTime" msgstr "Samba: 最終パスワード失敗時刻(sambaBadPasswordTime)" #: -:- msgid "LDAP|Attribute|sambaBoolOption" msgstr "Samba: 真偽値オプション(sambaBoolOption)" #: -:- msgid "LDAP|Attribute|sambaDomainName" msgstr "Samba: ドメイン名(sambaDomainName)" #: -:- msgid "LDAP|Attribute|sambaForceLogoff" msgstr "Samba: 強制ログオフ(sambaForceLogoff)" #: -:- msgid "LDAP|Attribute|sambaGroupType" msgstr "Samba: グループ種別(sambaGroupType)" #: -:- msgid "LDAP|Attribute|sambaHomeDrive" msgstr "Samba: ホームドライブ(sambaHomeDrive)" #: -:- msgid "LDAP|Attribute|sambaHomePath" msgstr "Samba: ホームパス(sambaHomePath)" #: -:- msgid "LDAP|Attribute|sambaIntegerOption" msgstr "Samba: 整数値オプション(sambaIntegerOption)" #: -:- msgid "LDAP|Attribute|sambaKickoffTime" msgstr "Samba: 自動ログオフ時刻(sambaKickoffTime)" #: -:- msgid "LDAP|Attribute|sambaLMPassword" msgstr "Samba: LANマネージャパスワード(sambaLMPassword)" #: -:- msgid "LDAP|Attribute|sambaLockoutDuration" msgstr "Samba: ロックアウト期間(sambaLockoutDuration)" #: -:- msgid "LDAP|Attribute|sambaLockoutObservationWindow" msgstr "Samba: ロックアウト監視時間(sambaLockoutObservationWindow)" #: -:- msgid "LDAP|Attribute|sambaLockoutThreshold" msgstr "Samba: ロックアウト閾値(sambaLockoutThreshold)" #: -:- msgid "LDAP|Attribute|sambaLogoffTime" msgstr "Samba: ログオフ時刻(sambaLogoffTime)" #: -:- msgid "LDAP|Attribute|sambaLogonHours" msgstr "Samba: ログオン時間(sambaLogonHours)" #: -:- msgid "LDAP|Attribute|sambaLogonScript" msgstr "Samba: ログオンスクリプト(sambaLogonScript)" #: -:- msgid "LDAP|Attribute|sambaLogonTime" msgstr "Samba: ログオン時刻(sambaLogonTime)" #: -:- msgid "LDAP|Attribute|sambaLogonToChgPwd" msgstr "Samba: パスワード変更用ログオン(sambaLogonToChgPwd)" #: -:- msgid "LDAP|Attribute|sambaMaxPwdAge" msgstr "Samba: 最大パスワード寿命(sambaMaxPwdAge)" #: -:- msgid "LDAP|Attribute|sambaMinPwdAge" msgstr "Samba: 最小パスワード寿命(sambaMinPwdAge)" #: -:- msgid "LDAP|Attribute|sambaMinPwdLength" msgstr "Samba: 最小パスワード長(sambaMinPwdLength)" #: -:- msgid "LDAP|Attribute|sambaMungedDial" msgstr "Samba: 復元不能ダイヤル(sambaMungedDial)" #: -:- msgid "LDAP|Attribute|sambaNTPassword" msgstr "Samba: NTパスワード(sambaNTPassword)" #: -:- msgid "LDAP|Attribute|sambaNextGroupRid" msgstr "Samba: 次のグループRID(sambaNextGroupRid)" #: -:- msgid "LDAP|Attribute|sambaNextRid" msgstr "Samba: 次のRID(sambaNextRid0" #: -:- msgid "LDAP|Attribute|sambaNextUserRid" msgstr "Samba: 次のユーザRID(sambaNextUserRid)" #: -:- msgid "LDAP|Attribute|sambaOptionName" msgstr "Samba: オプション名(sambaOptionName)" #: -:- msgid "LDAP|Attribute|sambaPasswordHistory" msgstr "Samba: パスワード履歴(sambaPasswordHistory)" #: -:- msgid "LDAP|Attribute|sambaPrimaryGroupSID" msgstr "Samba: プライマリグループSID(sambaPrimaryGroupSID)" #: -:- msgid "LDAP|Attribute|sambaProfilePath" msgstr "Samba: プロフィールパス(sambaProfilePath)" #: -:- msgid "LDAP|Attribute|sambaPwdCanChange" msgstr "Samba: パスワード変更可能時刻(sambaPwdCanChange)" #: -:- msgid "LDAP|Attribute|sambaPwdHistoryLength" msgstr "Samba: パスワード履歴長(sambaPwdHistoryLength)" #: -:- msgid "LDAP|Attribute|sambaPwdLastSet" msgstr "Samba: パスワード最終変更時刻(sambaPwdLastSet)" #: -:- msgid "LDAP|Attribute|sambaPwdMustChange" msgstr "Samba: パスワード失効時刻(sambaPwdMustChange)" #: -:- msgid "LDAP|Attribute|sambaRefuseMachinePwdChange" msgstr "Samba: マシンパスワード変更拒否(sambaRefuseMachinePwdChange)" #: -:- msgid "LDAP|Attribute|sambaSID" msgstr "Samba: セキュリティID(sambaSID)" #: -:- msgid "LDAP|Attribute|sambaSIDList" msgstr "Samba; セキュリティID一覧(sambaSIDList)" #: -:- msgid "LDAP|Attribute|sambaShareName" msgstr "Samba: 共有名(sambaShareName)" #: -:- msgid "LDAP|Attribute|sambaStringListOption" msgstr "Samba: 文字列リストオプション(sambaStringListOption)" #: -:- msgid "LDAP|Attribute|sambaStringOption" msgstr "Samba: 文字列値オプション(sambaStringOption)" #: -:- msgid "LDAP|Attribute|sambaTrustFlags" msgstr "Samba: 信用フラグ(sambaTrustFlags)" #: -:- msgid "LDAP|Attribute|sambaUserWorkstations" msgstr "Samba: ユーザのワークステーション一覧(sambaUserWorkstations)" #: -:- msgid "LDAP|Attribute|searchGuide" msgstr "検索案内(searchGuide)" #: -:- msgid "LDAP|Attribute|secretary" msgstr "秘書(secretary)" #: -:- msgid "LDAP|Attribute|seeAlso" msgstr "参照(seeAlso)" #: -:- msgid "LDAP|Attribute|serialNumber" msgstr "通し番号(serialNumber)" #: -:- msgid "LDAP|Attribute|shadowExpire" msgstr "シャドーパスワード失効日数(shadowExpire)" #: -:- msgid "LDAP|Attribute|shadowFlag" msgstr "シャドーフラグ(shadowFlag)" #: -:- msgid "LDAP|Attribute|shadowInactive" msgstr "シャドーパスワード無効日(shadowInactive)" #: -:- msgid "LDAP|Attribute|shadowLastChange" msgstr "最終シャドーパスワード更新日(shadowLastChange)" #: -:- msgid "LDAP|Attribute|shadowMax" msgstr "最大シャドーパスワード長(shadowMax)" #: -:- msgid "LDAP|Attribute|shadowMin" msgstr "最小シャドーパスワード長(shadowMin<)" #: -:- msgid "LDAP|Attribute|shadowWarning" msgstr "シャドーパスワード失効警告日(shadowWarning)" #: -:- msgid "LDAP|Attribute|singleLevelQuality" msgstr "単一レベル品質(singleLevelQuality)" #: -:- msgid "LDAP|Attribute|sn" msgstr "姓(sn)" #: -:- msgid "LDAP|Attribute|st" msgstr "国・州(st)" #: -:- msgid "LDAP|Attribute|stateOrProvinceName" msgstr "州・県・地方名(stateOrProvinceName)" #: -:- msgid "LDAP|Attribute|street" msgstr "通り(street)" #: -:- msgid "LDAP|Attribute|streetAddress" msgstr "通りの住所(streatAddress)" #: -:- msgid "LDAP|Attribute|structuralObjectClass" msgstr "構造的なオブジェクトクラス(structuralObjectClass)" #: -:- msgid "LDAP|Attribute|subschemaSubentry" msgstr "サブスキーマのサブエントリ(subschemaSubentry)" #: -:- msgid "LDAP|Attribute|subtreeMaximumQuality" msgstr "サブツリー最大品質(subtreeMaximumQuality)" #: -:- msgid "LDAP|Attribute|subtreeMinimumQuality" msgstr "サブツリー最小品質(subtreeMinimumQuality)" #: -:- msgid "LDAP|Attribute|supportedAlgorithms" msgstr "対応アルゴリズム(supportedAlgorithms)" #: -:- msgid "LDAP|Attribute|supportedApplicationContext" msgstr "対応応用コンテクスト(supportedApplicationContext)" #: -:- msgid "LDAP|Attribute|supportedControl" msgstr "対応コントロール(supportedControl)" #: -:- msgid "LDAP|Attribute|supportedExtension" msgstr "対応拡張(supportedExtension)" #: -:- msgid "LDAP|Attribute|supportedFeatures" msgstr "対応機能(supportedFeatures)" #: -:- msgid "LDAP|Attribute|supportedLDAPVersion" msgstr "対応LDAPバージョン(supportedLDAPVersion)" #: -:- msgid "LDAP|Attribute|supportedSASLMechanisms" msgstr "対応SASLメカニズム(supportedSASLMechanisms)" #: -:- msgid "LDAP|Attribute|surname" msgstr "姓(surname)" #: -:- msgid "LDAP|Attribute|telephoneNumber" msgstr "電話番号(telephoneNumber)" #: -:- msgid "LDAP|Attribute|teletexTerminalIdentifier" msgstr "文字多重放送端末識別子(teletexTerminalIdentifier)" #: -:- msgid "LDAP|Attribute|telexNumber" msgstr "テレックス番号(telexNumber)" #: -:- msgid "LDAP|Attribute|textEncodedORAddress" msgstr "テキスト符号化されたORアドレス(textEncodedORAddress)" #: -:- msgid "LDAP|Attribute|title" msgstr "タイトル(title)" #: -:- msgid "LDAP|Attribute|uid" msgstr "ユーザID(uid)" #: -:- msgid "LDAP|Attribute|uidNumber" msgstr "ユーザID番号(uidNumber)" #: -:- msgid "LDAP|Attribute|uniqueIdentifier" msgstr "一意の識別子(uniqueIdentifier)" #: -:- msgid "LDAP|Attribute|uniqueMember" msgstr "重複のないメンバー(uniqueNumber)" #: -:- msgid "LDAP|Attribute|userCertificate" msgstr "ユーザ: 証明書(userCertificate)" #: -:- msgid "LDAP|Attribute|userClass" msgstr "ユーザ: クラス(userClass)" #: -:- msgid "LDAP|Attribute|userPKCS12" msgstr "ユーザ: PKCS12(userPKCS12)" #: -:- msgid "LDAP|Attribute|userPassword" msgstr "ユーザ: パスワード(userPassword)" #: -:- msgid "LDAP|Attribute|userSMIMECertificate" msgstr "ユーザ: S/MIME証明書(userSMIMECertificate)" #: -:- msgid "LDAP|Attribute|userid" msgstr "ユーザID(userid)" #: -:- msgid "LDAP|Attribute|vendorName" msgstr "ベンダー名(vendorName)" #: -:- msgid "LDAP|Attribute|vendorVersion" msgstr "ベンダーバージョン(vendorVersion)" #: -:- msgid "LDAP|Attribute|x121Address" msgstr "X.121アドレス(x121Address)" #: -:- msgid "LDAP|Attribute|x500UniqueIdentifier" msgstr "X.500 一意の識別子(x500UniqueIdentifier)" #: -:- msgid "" "LDAP|Description|Attribute|aliasedObjectName|RFC4512: name of aliased object" msgstr "RFC4512: 別名を付けられたオブジェクトの名前" #: -:- msgid "LDAP|Description|Attribute|altServer|RFC4512: alternative servers" msgstr "RFC4512: 代替サーバ" #: -:- msgid "" "LDAP|Description|Attribute|associatedDomain|RFC1274: domain associated with " "object" msgstr "RFC1274: オブジェクトに関連付けられたドメイン" #: -:- msgid "" "LDAP|Description|Attribute|associatedName|RFC1274: DN of entry associated " "with domain" msgstr "RFC1274: ドメインに関連付けられたエントリのDN" #: -:- msgid "LDAP|Description|Attribute|attributeTypes|RFC4512: attribute types" msgstr "RFC4512: 属性の種類" #: -:- msgid "LDAP|Description|Attribute|audio|RFC1274: audio (u-law)" msgstr "RFC1274: 音声(u-law)" #: -:- msgid "" "LDAP|Description|Attribute|authorityRevocationList|RFC2256: X.509 authority " "revocation list, use ;binary" msgstr "RFC2256: X.509失効証明書一覧。;binaryを使うこと" #: -:- msgid "LDAP|Description|Attribute|bootFile|Boot image name" msgstr "起動イメージ名" #: -:- msgid "LDAP|Description|Attribute|bootParameter|rpc.bootparamd parameter" msgstr "rpc.bootparamdのパラメタ" #: -:- msgid "LDAP|Description|Attribute|buildingName|RFC1274: name of building" msgstr "RFC1274: 建物の名前" #: -:- msgid "LDAP|Description|Attribute|businessCategory|RFC2256: business category" msgstr "RFC2256: 業種" #: -:- msgid "" "LDAP|Description|Attribute|cACertificate|RFC2256: X.509 CA certificate, use ;" "binary" msgstr "RFC2256: X.509 CA証明書。;binaryを使うこと" #: -:- msgid "" "LDAP|Description|Attribute|carLicense|RFC2798: vehicle license or " "registration plate" msgstr "RFC2798: 運転免許証あるいは登録番号" #: -:- msgid "" "LDAP|Description|Attribute|certificateRevocationList|RFC2256: X.509 " "certificate revocation list, use ;binary" msgstr "RFC2256: X.509証明書失効一覧。;binaryを使うこと" #: -:- msgid "" "LDAP|Description|Attribute|cn|RFC4519: common name(s) for which the entity " "is known by" msgstr "RFC4519: エントリの一般的な名前" #: -:- msgid "LDAP|Description|Attribute|co|RFC1274: friendly country name" msgstr "RFC1274: 友好国の名前" #: -:- msgid "" "LDAP|Description|Attribute|createTimestamp|RFC4512: time which object was " "created" msgstr "RFC4512: オブジェクトが作成された時刻" #: -:- msgid "LDAP|Description|Attribute|creatorsName|RFC4512: name of creator" msgstr "RFC4512: 作成者の名前" #: -:- msgid "" "LDAP|Description|Attribute|crossCertificatePair|RFC2256: X.509 cross " "certificate pair, use ;binary" msgstr "RFC2256: X.509相互認証組。;binaryを使うこと" #: -:- msgid "LDAP|Description|Attribute|c|RFC2256: ISO-3166 country 2-letter code" msgstr "RFC2256: ISO-3166で定義される2文字の国コード" #: -:- msgid "LDAP|Description|Attribute|dITRedirect|RFC1274: DIT Redirect" msgstr "RFC1274: DITのリダイレクト先" #: -:- msgid "LDAP|Description|Attribute|dSAQuality|RFC1274: DSA Quality" msgstr "RFC1274: ディレクトリシステムエージェント(DSA)の特性" #: -:- msgid "LDAP|Description|Attribute|dc|RFC1274/2247: domain component" msgstr "RFC1274/2247: ドメインの要素" #: -:- msgid "" "LDAP|Description|Attribute|deltaRevocationList|RFC2256: delta revocation " "list; use ;binary" msgstr "RFC2256: 差分失効一覧。;binaryを使うこと" #: -:- msgid "" "LDAP|Description|Attribute|departmentNumber|RFC2798: identifies a department " "within an organization" msgstr "RFC2798: 組織内の部門を一意に識別する番号" #: -:- msgid "LDAP|Description|Attribute|description|RFC4519: descriptive information" msgstr "RFC4519: 説明的な情報" #: -:- msgid "" "LDAP|Description|Attribute|destinationIndicator|RFC2256: destination " "indicator" msgstr "RFC2256: 行き先を表示するもの" #: -:- msgid "" "LDAP|Description|Attribute|displayName|RFC2798: preferred name to be used " "when displaying entries" msgstr "RFC2798: エントリを表示するときに使いたい名前" #: -:- msgid "" "LDAP|Description|Attribute|distinguishedName|RFC4519: common supertype of DN " "attributes" msgstr "RFC4519: DN属性共通のスーパータイプ" #: -:- msgid "LDAP|Description|Attribute|dmdName|RFC2256: name of DMD" msgstr "RFC2256: ディレクトリ管理ドメイン(DMD)の名前" #: -:- msgid "LDAP|Description|Attribute|dnQualifier|RFC2256: DN qualifier" msgstr "RFC1274: DN限定詞" #: -:- msgid "" "LDAP|Description|Attribute|documentAuthor|RFC1274: DN of author of document" msgstr "RFC1274: 文書作成者のDN" #: -:- msgid "" "LDAP|Description|Attribute|documentIdentifier|RFC1274: unique identifier of " "document" msgstr "RFC1274: 文書を一意に識別する名前" #: -:- msgid "" "LDAP|Description|Attribute|documentLocation|RFC1274: location of document " "original" msgstr "RFC1274: 元文書の場所" #: -:- msgid "" "LDAP|Description|Attribute|documentPublisher|RFC1274: publisher of document" msgstr "RFC1274: 文書の発行者" #: -:- msgid "LDAP|Description|Attribute|documentTitle|RFC1274: title of document" msgstr "RFC1274: 文書のタイトル" #: -:- msgid "LDAP|Description|Attribute|documentVersion|RFC1274: version of document" msgstr "RFC1274: 文書のバージョン" #: -:- msgid "LDAP|Description|Attribute|drink|RFC1274: favorite drink" msgstr "RFC1274: 好きな飲み物" #: -:- msgid "LDAP|Description|Attribute|dynamicSubtrees|RFC2589: dynamic subtrees" msgstr "RFC2589: 動的なサブツリー" #: -:- msgid "" "LDAP|Description|Attribute|email|RFC3280: legacy attribute for email " "addresses in DNs" msgstr "RFC3280: 昔、DNの中のEメールアドレスに使われていた属性" #: -:- msgid "" "LDAP|Description|Attribute|employeeNumber|RFC2798: numerically identifies an " "employee within an organization" msgstr "RFC2798: 組織内の従業員を一意に識別する番号" #: -:- msgid "" "LDAP|Description|Attribute|employeeType|RFC2798: type of employment for a " "person" msgstr "RFC2798: 従業員の種類" #: -:- msgid "" "LDAP|Description|Attribute|enhancedSearchGuide|RFC2256: enhanced search guide" msgstr "RFC2256: 拡張された検索案内" #: -:- msgid "LDAP|Description|Attribute|entryDN|DN of the entry" msgstr "エントリのDN" #: -:- msgid "LDAP|Description|Attribute|entryTtl|RFC2589: entry time-to-live" msgstr "RFC2589: エントリの生存時間" #: -:- msgid "LDAP|Description|Attribute|entryUUID|UUID of the entry" msgstr "エントリのUUID" #: -:- msgid "" "LDAP|Description|Attribute|facsimileTelephoneNumber|RFC2256: Facsimile (Fax) " "Telephone Number" msgstr "RFC2256: FAX番号" #: -:- msgid "LDAP|Description|Attribute|gecos|The GECOS field; the common name" msgstr "GECOSフィールド。つまり共通名" #: -:- msgid "" "LDAP|Description|Attribute|generationQualifier|RFC2256: name qualifier " "indicating a generation" msgstr "RFC2256: 世代を識別する名前限定詞" #: -:- msgid "" "LDAP|Description|Attribute|gidNumber|RFC2307: An integer uniquely " "identifying a group in an administrative domain" msgstr "RFC2307: 管理ドメイン内のグループを一意に識別する整数値" #: -:- msgid "" "LDAP|Description|Attribute|givenName|RFC2256: first name(s) for which the " "entity is known by" msgstr "RFC2256: 実体がわかる名前" #: -:- msgid "LDAP|Description|Attribute|hasSubordinates|X.501: entry has children" msgstr "X.501: エントリがこどもを持つか" #: -:- msgid "" "LDAP|Description|Attribute|homeDirectory|The absolute path to the home " "directory" msgstr "ホームディレクトリの絶対パス" #: -:- msgid "LDAP|Description|Attribute|homePhone|RFC1274: home telephone number" msgstr "RFC1274: 自宅の電話番号" #: -:- msgid "" "LDAP|Description|Attribute|homePostalAddress|RFC1274: home postal address" msgstr "RFC1274: 自宅の郵便の宛先" #: -:- msgid "LDAP|Description|Attribute|host|RFC1274: host computer" msgstr "RFC1274: ホストコンピュータ" #: -:- msgid "LDAP|Description|Attribute|houseIdentifier|RFC2256: house identifier" msgstr "RFC2256: 住宅識別子" #: -:- msgid "LDAP|Description|Attribute|info|RFC1274: general information" msgstr "RFC1274: 一般的な情報" #: -:- msgid "" "LDAP|Description|Attribute|initials|RFC2256: initials of some or all of " "names, but not the surname(s)." msgstr "RFC2256: 名前(姓を除く)の頭文字" #: -:- msgid "" "LDAP|Description|Attribute|internationaliSDNNumber|RFC2256: international " "ISDN number" msgstr "RFC2256: 国際ISDN番号" #: -:- msgid "LDAP|Description|Attribute|ipHostNumber|IP address" msgstr "IPアドレス" #: -:- msgid "LDAP|Description|Attribute|ipNetmaskNumber|IP netmask" msgstr "IPネットマスク" #: -:- msgid "LDAP|Description|Attribute|ipNetworkNumber|IP network" msgstr "IPネットワーク" #: -:- msgid "LDAP|Description|Attribute|janetMailbox|RFC1274: Janet mailbox" msgstr "RFC1274: JANETのメールボックス" #: -:- msgid "LDAP|Description|Attribute|jpegPhoto|RFC2798: a JPEG image" msgstr "RFC2798: JPEG画像" #: -:- msgid "" "LDAP|Description|Attribute|knowledgeInformation|RFC2256: knowledge " "information" msgstr "RFC2256: 知識情報" #: -:- msgid "" "LDAP|Description|Attribute|labeledURI|RFC2079: Uniform Resource Identifier " "with optional label" msgstr "RFC2079: 付加ラベル付き統一資源識別子(URI)" #: -:- msgid "LDAP|Description|Attribute|ldapSyntaxes|RFC4512: LDAP syntaxes" msgstr "RFC4512: LDAPの構文" #: -:- msgid "LDAP|Description|Attribute|loginShell|The path to the login shell" msgstr "ログインシェルのパス" #: -:- msgid "" "LDAP|Description|Attribute|l|RFC2256: locality which this object resides in" msgstr "RFC2256: オブジェクトが住んでいる地域" #: -:- msgid "LDAP|Description|Attribute|macAddress|MAC address" msgstr "MACアドレス" #: -:- msgid "" "LDAP|Description|Attribute|mailPreferenceOption|RFC1274: mail preference " "option" msgstr "RFC1274: メール設定オプション" #: -:- msgid "LDAP|Description|Attribute|mail|RFC1274: RFC822 Mailbox" msgstr "RFC1274: RFC822で定義されているメールボックス" #: -:- msgid "LDAP|Description|Attribute|manager|RFC1274: DN of manager" msgstr "RFC1274: 管理者のDN" #: -:- msgid "LDAP|Description|Attribute|matchingRuleUse|RFC4512: matching rule uses" msgstr "RFC4512: 使用するマッチ規則" #: -:- msgid "LDAP|Description|Attribute|matchingRules|RFC4512: matching rules" msgstr "RFC4512: マッチ規則" #: -:- msgid "LDAP|Description|Attribute|member|RFC2256: member of a group" msgstr "RFC2256: グループのメンバー" #: -:- msgid "LDAP|Description|Attribute|mobile|RFC1274: mobile telephone number" msgstr "RFC1274: 携帯電話の電話番号" #: -:- msgid "LDAP|Description|Attribute|modifiersName|RFC4512: name of last modifier" msgstr "RFC4512: 最終変更者の名前" #: -:- msgid "" "LDAP|Description|Attribute|modifyTimestamp|RFC4512: time which object was " "last modified" msgstr "RFC4512: オブジェクトが最後に変更された時刻" #: -:- msgid "" "LDAP|Description|Attribute|name|RFC4519: common supertype of name attributes" msgstr "RFC4519: 名前属性の共通のスーパータイプ" #: -:- msgid "LDAP|Description|Attribute|namingContexts|RFC4512: naming contexts" msgstr "RFC4512: 名前付けの文脈" #: -:- msgid "LDAP|Description|Attribute|nisNetgroupTriple|Netgroup triple" msgstr "ネットグループトリプル" #: -:- msgid "LDAP|Description|Attribute|objectClasses|RFC4512: object classes" msgstr "RFC4512: オブジェクトが属するクラス" #: -:- msgid "" "LDAP|Description|Attribute|objectClass|RFC4512: object classes of the entity" msgstr "RFC4512: 実体のオブジェクトクラス" #: -:- msgid "LDAP|Description|Attribute|olcAccess|Access Control List" msgstr "アクセス制御リスト" #: -:- msgid "" "LDAP|Description|Attribute|olcAddContentAcl|Check ACLs against content of " "Add ops" msgstr "追加操作の内容に対するアクセス制御リストをチェック" #: -:- msgid "LDAP|Description|Attribute|olcAllows|Allowed set of deprecated features" msgstr "使うことを許可する非推奨の機能群" #: -:- msgid "" "LDAP|Description|Attribute|olcArgsFile|File for slapd command line options" msgstr "slapdのコマンドラインオプションで指定した設定ファイル" #: -:- msgid "LDAP|Description|Attribute|olcAttributeTypes|OpenLDAP attributeTypes" msgstr "OpenLDAP用のattributeTypes" #: -:- msgid "LDAP|Description|Attribute|olcBackend|A type of backend" msgstr "バックエンドの種類" #: -:- msgid "" "LDAP|Description|Attribute|olcConfigDir|Directory for slapd configuration " "backend" msgstr "slapd設定バックエンド用のディレクトリ" #: -:- msgid "" "LDAP|Description|Attribute|olcConfigFile|File for slapd configuration " "directives" msgstr "slapd設定ディレクティブ用のファイル" #: -:- msgid "" "LDAP|Description|Attribute|olcDatabase|The backend type for a database " "instance" msgstr "データベースインスタンス用のバックエンドの種類" #: -:- msgid "" "LDAP|Description|Attribute|olcDbCacheFree|Number of extra entries to free " "when max is reached" msgstr "最大数に達したときに開放する余分なエントリ数" #: -:- msgid "LDAP|Description|Attribute|olcDbCacheSize|Entry cache size in entries" msgstr "エントリをキャッシュする量" #: -:- msgid "" "LDAP|Description|Attribute|olcDbCheckpoint|Database checkpoint interval in " "kbytes and minutes" msgstr "データベースチェックポイント間隔(Kバイトと分で指定)" #: -:- msgid "" "LDAP|Description|Attribute|olcDbChecksum|Enable database checksum validation" msgstr "データベースのチェックサム検証を有効にする" #: -:- msgid "" "LDAP|Description|Attribute|olcDbConfig|BerkeleyDB DB_CONFIG configuration " "directives" msgstr "バークレイDB(BDB)のDB_CONFIG設定ディレクティブ" #: -:- msgid "" "LDAP|Description|Attribute|olcDbCryptFile|Pathname of file containing the DB " "encryption key" msgstr "DB暗号化鍵を含むファイルのパス名" #: -:- msgid "LDAP|Description|Attribute|olcDbCryptKey|DB encryption key" msgstr "DB暗号化鍵" #: -:- msgid "LDAP|Description|Attribute|olcDbDNcacheSize|DN cache size" msgstr "DNのキャッシュ量" #: -:- msgid "" "LDAP|Description|Attribute|olcDbDirectory|Directory for database content" msgstr "データベースの内容用のディレクトリ" #: -:- msgid "" "LDAP|Description|Attribute|olcDbDirtyRead|Allow reads of uncommitted data" msgstr "コミット前のデータの読み込みを許可するかどうか" #: -:- msgid "LDAP|Description|Attribute|olcDbIDLcacheSize|IDL cache size in IDLs" msgstr "IDLのキャッシュ量" #: -:- msgid "LDAP|Description|Attribute|olcDbIndex|Attribute index parameters" msgstr "属性索引用のパラメタ" #: -:- msgid "" "LDAP|Description|Attribute|olcDbLinearIndex|Index attributes one at a time" msgstr "一度に一つだけ属性を索引化する" #: -:- msgid "LDAP|Description|Attribute|olcDbLockDetect|Deadlock detection algorithm" msgstr "デッドロック検出アルゴリズム" #: -:- msgid "LDAP|Description|Attribute|olcDbMode|Unix permissions of database files" msgstr "データベースファイルのUNIXのパーミッション" #: -:- msgid "" "LDAP|Description|Attribute|olcDbNoSync|Disable synchronous database writes" msgstr "データベースへの同期書き込みを無効にする" #: -:- msgid "" "LDAP|Description|Attribute|olcDbPageSize|Page size of specified DB, in Kbytes" msgstr "指定したデータベースのページサイズ(Kバイトで指定)" #: -:- msgid "" "LDAP|Description|Attribute|olcDbSearchStack|Depth of search stack in IDLs" msgstr "IDLを<検索するスタックの深さ" #: -:- msgid "LDAP|Description|Attribute|olcDbShmKey|Key for shared memory region" msgstr "共有メモリ領域のキー" #: -:- msgid "" "LDAP|Description|Attribute|olcDitContentRules|OpenLDAP DIT content rules" msgstr "OpenLDAPディレクトリ情報ツリー(DIT)の内容規則" #: -:- msgid "LDAP|Description|Attribute|olcLdapSyntaxes|OpenLDAP ldapSyntax" msgstr "OpenLDAP用のLDAPの構文" #: -:- msgid "LDAP|Description|Attribute|olcObjectClasses|OpenLDAP object classes" msgstr "OpenLDAP用のオブジェクトクラス" #: -:- msgid "" "LDAP|Description|Attribute|olcSortVals|Attributes whose values will always " "be sorted" msgstr "常に値を並び替えておく属性(複数)" #: -:- msgid "" "LDAP|Description|Attribute|organizationalStatus|RFC1274: organizational " "status" msgstr "RFC1274: 組織の状態" #: -:- msgid "" "LDAP|Description|Attribute|ou|RFC2256: organizational unit this object " "belongs to" msgstr "RFC2256: このオブジェクトが属している組織単位" #: -:- msgid "LDAP|Description|Attribute|owner|RFC2256: owner (of the object)" msgstr "RFC2256: このオブジェクトの所有者" #: -:- msgid "" "LDAP|Description|Attribute|o|RFC2256: organization this object belongs to" msgstr "RFC2256: このオブジェクトが属する組織" #: -:- msgid "LDAP|Description|Attribute|pager|RFC1274: pager telephone number" msgstr "RFC1274: ポケベル番号" #: -:- msgid "" "LDAP|Description|Attribute|personalSignature|RFC1274: Personal Signature (G3 " "fax)" msgstr "RFC1274: 個人的な署名 (G3 FAX)" #: -:- msgid "LDAP|Description|Attribute|personalTitle|RFC1274: personal title" msgstr "RFC1274: 個人的な肩書き" #: -:- msgid "LDAP|Description|Attribute|photo|RFC1274: photo (G3 fax)" msgstr "RFC1274: 写真 (G3 FAX)" #: -:- msgid "" "LDAP|Description|Attribute|physicalDeliveryOfficeName|RFC2256: Physical " "Delivery Office Name" msgstr "RFC2256: 現物引き渡しオフィス名" #: -:- msgid "LDAP|Description|Attribute|postOfficeBox|RFC2256: Post Office Box" msgstr "RFC2256: 私書箱" #: -:- msgid "LDAP|Description|Attribute|postalAddress|RFC2256: postal address" msgstr "RFC2256: 郵便の宛先" #: -:- msgid "LDAP|Description|Attribute|postalCode|RFC2256: postal code" msgstr "RFC2256: 郵便番号" #: -:- msgid "" "LDAP|Description|Attribute|preferredDeliveryMethod|RFC2256: preferred " "delivery method" msgstr "RFC2256: 希望する配達方法" #: -:- msgid "" "LDAP|Description|Attribute|preferredLanguage|RFC2798: preferred written or " "spoken language for a person" msgstr "RFC2256: 希望する書き・話しに使う言語" #: -:- msgid "" "LDAP|Description|Attribute|presentationAddress|RFC2256: presentation address" msgstr "RFC2256: OSIプレゼンテーションアドレス" #: -:- msgid "" "LDAP|Description|Attribute|protocolInformation|RFC2256: protocol information" msgstr "RFC2256: プロトコル情報" #: -:- msgid "" "LDAP|Description|Attribute|pseudonym|X.520(4th): pseudonym for the object" msgstr "X.520(4th): オブジェクトの仮名" #: -:- msgid "LDAP|Description|Attribute|ref|RFC3296: subordinate referral URL" msgstr "RFC3296: 下位の照会URL" #: -:- msgid "" "LDAP|Description|Attribute|registeredAddress|RFC2256: registered postal " "address" msgstr "RFC2256: 登録されている郵便の宛先" #: -:- msgid "LDAP|Description|Attribute|roleOccupant|RFC2256: occupant of role" msgstr "RFC2256: 居住者の役割" #: -:- msgid "LDAP|Description|Attribute|roomNumber|RFC1274: room number" msgstr "RFC1274: 部屋番号" #: -:- msgid "LDAP|Description|Attribute|sambaAcctFlags|Account Flags" msgstr "アカウントフラグ" #: -:- msgid "" "LDAP|Description|Attribute|sambaAlgorithmicRidBase|Base at which the samba " "RID generation algorithm should operate" msgstr "SambaがRID生成アルゴリズムを実行するときに使用するベースとなるRID" #: -:- msgid "" "LDAP|Description|Attribute|sambaBadPasswordCount|Bad password attempt count" msgstr "間違ったパスワードを試みた回数" #: -:- msgid "" "LDAP|Description|Attribute|sambaBadPasswordTime|Time of the last bad " "password attempt" msgstr "最後に間違ったパスワードを試みた時間" #: -:- msgid "LDAP|Description|Attribute|sambaBoolOption|A boolean option" msgstr "真偽値のオプション" #: -:- msgid "" "LDAP|Description|Attribute|sambaDomainName|Windows NT domain to which the " "user belongs" msgstr "ユーザが属するWindows NTドメイン" #: -:- msgid "" "LDAP|Description|Attribute|sambaForceLogoff|Disconnect Users outside logon " "hours (default: -1 => off, 0 => on)" msgstr "ログオン時間後に<なると強制切断する(デフォルト: -1 => 無効, 0 => 有効)" #: -:- msgid "LDAP|Description|Attribute|sambaGroupType|NT Group Type" msgstr "NTグループ種類" #: -:- msgid "" "LDAP|Description|Attribute|sambaHomeDrive|Driver letter of home directory " "mapping" msgstr "ホームディレクトリに割り当てるドライブ文字" #: -:- msgid "LDAP|Description|Attribute|sambaHomePath|Home directory UNC path" msgstr "ホームディレクトリのUNCパス" #: -:- msgid "LDAP|Description|Attribute|sambaIntegerOption|An integer option" msgstr "整数値のオプション" #: -:- msgid "" "LDAP|Description|Attribute|sambaKickoffTime|Timestamp of when the user will " "be logged off automatically" msgstr "ユーザが自動的にログオフしたときの時間" #: -:- msgid "LDAP|Description|Attribute|sambaLMPassword|LanManager Password" msgstr "LANマネージャ用のパスワード" #: -:- msgid "" "LDAP|Description|Attribute|sambaLockoutDuration|Lockout duration in minutes " "(default: 30, -1 => forever)" msgstr "ロックアウト期間(default: 30, -1 => 永遠に)" #: -:- msgid "" "LDAP|Description|Attribute|sambaLockoutObservationWindow|Reset time after " "lockout in minutes (default: 30)" msgstr "ロックアウト後にリセットする時間(分) (デフォルト: 30)" #: -:- msgid "" "LDAP|Description|Attribute|sambaLockoutThreshold|Lockout users after bad " "logon attempts (default: 0 => off)" msgstr "" "指定した回数ログオンに失敗したあとにユーザをロックアウトする (デフォルト: 0 " "=> 無効)" #: -:- msgid "LDAP|Description|Attribute|sambaLogoffTime|Timestamp of last logoff" msgstr "最後にログオフした時刻" #: -:- msgid "LDAP|Description|Attribute|sambaLogonHours|Logon Hours" msgstr "ログオン時間" #: -:- msgid "LDAP|Description|Attribute|sambaLogonScript|Logon script path" msgstr "ログオンスクリプトパス" #: -:- msgid "LDAP|Description|Attribute|sambaLogonTime|Timestamp of last logon" msgstr "最後にログオンした時刻" #: -:- msgid "" "LDAP|Description|Attribute|sambaLogonToChgPwd|Force Users to logon for " "password change (default: 0 => off, 2 => on)" msgstr "" "パスワード変更のために強制的にユーザをログオンさせる (デフォルト: 0 => 無効, " "2 => 有効)" #: -:- msgid "" "LDAP|Description|Attribute|sambaMaxPwdAge|Maximum password age, in seconds " "(default: -1 => never expire passwords)" msgstr "" "パスワードが失効するまでの時間(分) (デフォルト: -1 => パスワードは失効しない)" #: -:- msgid "" "LDAP|Description|Attribute|sambaMinPwdAge|Minimum password age, in seconds " "(default: 0 => allow immediate password change)" msgstr "" "パスワードを変更できるようになるまでの時間(分) (デフォルト: 0 => すぐにパス" "ワードを変更可能)" #: -:- msgid "" "LDAP|Description|Attribute|sambaMinPwdLength|Minimal password length " "(default: 5)" msgstr "最小のパスワード長 (デフォルト; 5)" #: -:- msgid "" "LDAP|Description|Attribute|sambaMungedDial|Base64 encoded user parameter " "string" msgstr "Base64で符号化されたユーザパラメタ文字列" #: -:- msgid "" "LDAP|Description|Attribute|sambaNTPassword|MD4 hash of the unicode password" msgstr "Unicodeで符号化されたパスワードのMD4ハッシュ" #: -:- msgid "" "LDAP|Description|Attribute|sambaNextGroupRid|Next NT rid to give out for " "groups" msgstr "次のグループに割り当てるNT RID" #: -:- msgid "" "LDAP|Description|Attribute|sambaNextRid|Next NT rid to give out for anything" msgstr "次の任意のオブジェクトに割り当てるNT RID" #: -:- msgid "" "LDAP|Description|Attribute|sambaNextUserRid|Next NT rid to give our for users" msgstr "次のユーザに割り当てるNT RID" #: -:- msgid "LDAP|Description|Attribute|sambaOptionName|Option Name" msgstr "オプション名" #: -:- msgid "" "LDAP|Description|Attribute|sambaPasswordHistory|Concatenated MD4 hashes of " "the unicode passwords used on this account" msgstr "このアカウントで使用されたUnicodeパスワードのMD4ハッシュを結合したもの" #: -:- msgid "" "LDAP|Description|Attribute|sambaPrimaryGroupSID|Primary Group Security ID" msgstr "プライマリグループのセキュリティID" #: -:- msgid "LDAP|Description|Attribute|sambaProfilePath|Roaming profile path" msgstr "移動プロファイルのパス" #: -:- msgid "" "LDAP|Description|Attribute|sambaPwdCanChange|Timestamp of when the user is " "allowed to update the password" msgstr "ユーザがパスワードを更新できるようになったときの時刻" #: -:- msgid "" "LDAP|Description|Attribute|sambaPwdHistoryLength|Length of Password History " "Entries (default: 0 => off)" msgstr "パスワードの履歴を保存する世代数 (デフォルト: 0 => 無効)" #: -:- msgid "" "LDAP|Description|Attribute|sambaPwdLastSet|Timestamp of the last password " "update" msgstr "最後にパスワードを更新した時刻" #: -:- msgid "" "LDAP|Description|Attribute|sambaPwdMustChange|Timestamp of when the password " "will expire" msgstr "パスワードが失効する時刻" #: -:- msgid "" "LDAP|Description|Attribute|sambaRefuseMachinePwdChange|Allow Machine " "Password changes (default: 0 => off)" msgstr "" "マシンがパスワードを変更することを許可するかどうか (デフォルト: 0 => 拒否)" #: -:- msgid "LDAP|Description|Attribute|sambaSIDList|Security ID List" msgstr "セキュリティID一覧" #: -:- msgid "LDAP|Description|Attribute|sambaSID|Security ID" msgstr "セキュリティID" #: -:- msgid "LDAP|Description|Attribute|sambaShareName|Share Name" msgstr "共有名" #: -:- msgid "LDAP|Description|Attribute|sambaStringListOption|A string list option" msgstr "文字列リストのオプション" #: -:- msgid "LDAP|Description|Attribute|sambaStringOption|A string option" msgstr "文字列値のオプション" #: -:- msgid "LDAP|Description|Attribute|sambaTrustFlags|Trust Password Flags" msgstr "信用パスワードフラグ" #: -:- msgid "" "LDAP|Description|Attribute|sambaUserWorkstations|List of user workstations " "the user is allowed to logon to" msgstr "ユーザがログオン可能なワークステーション一覧" #: -:- msgid "" "LDAP|Description|Attribute|searchGuide|RFC2256: search guide, deprecated by " "enhancedSearchGuide" msgstr "RFC2256: 検索案内(enhancedSearchGuide導入により非推奨)" #: -:- msgid "LDAP|Description|Attribute|secretary|RFC1274: DN of secretary" msgstr "RFC1274: 秘書の共通名(DN)" #: -:- msgid "LDAP|Description|Attribute|seeAlso|RFC4519: DN of related object" msgstr "RFC4519: 関連したオブジェクトへの参照" #: -:- msgid "" "LDAP|Description|Attribute|serialNumber|RFC2256: serial number of the entity" msgstr "RFC2256: エントリの通し番号" #: -:- msgid "" "LDAP|Description|Attribute|singleLevelQuality|RFC1274: Single Level Quality" msgstr "RFC1274: 単一レベル品質" #: -:- msgid "" "LDAP|Description|Attribute|sn|RFC2256: last (family) name(s) for which the " "entity is known by" msgstr "RFFC2256: 実体だとわかる姓" #: -:- msgid "" "LDAP|Description|Attribute|street|RFC2256: street address of this object" msgstr "RFFC2256: オブジェクトの通りの住所" #: -:- msgid "" "LDAP|Description|Attribute|structuralObjectClass|RFC4512: structural object " "class of entry" msgstr "RFC4512: エントリの構造的なオブジェクトクラス" #: -:- msgid "" "LDAP|Description|Attribute|st|RFC2256: state or province which this object " "resides in" msgstr "RFFC2256: オブジェクトが住んでいる州・県・国" #: -:- msgid "" "LDAP|Description|Attribute|subschemaSubentry|RFC4512: name of controlling " "subschema entry" msgstr "RFC4512: 制御しているサブスキーマエントリの名前" #: -:- msgid "" "LDAP|Description|Attribute|subtreeMaximumQuality|RFC1274: Subtree Maximun " "Quality" msgstr "RFC1274: サブツリーの最大品質" #: -:- msgid "" "LDAP|Description|Attribute|subtreeMinimumQuality|RFC1274: Subtree Mininum " "Quality" msgstr "RFC1274: サブツリーの最小品質" #: -:- msgid "" "LDAP|Description|Attribute|supportedAlgorithms|RFC2256: supported algorithms" msgstr "RFC2256: 対応しているアルゴリズム" #: -:- msgid "" "LDAP|Description|Attribute|supportedApplicationContext|RFC2256: supported " "application context" msgstr "RFC2256: 対応している応用コンテクスト" #: -:- msgid "LDAP|Description|Attribute|supportedControl|RFC4512: supported controls" msgstr "RFC4512: 対応しているコントロール" #: -:- msgid "" "LDAP|Description|Attribute|supportedExtension|RFC4512: supported extended " "operations" msgstr "RFC4512: 対応している拡張操作" #: -:- msgid "" "LDAP|Description|Attribute|supportedFeatures|RFC4512: features supported by " "the server" msgstr "RFC4512: サーバが対応している機能" #: -:- msgid "" "LDAP|Description|Attribute|supportedLDAPVersion|RFC4512: supported LDAP " "versions" msgstr "RFC4512: 対応しているLDAPバージョン" #: -:- msgid "" "LDAP|Description|Attribute|supportedSASLMechanisms|RFC4512: supported SASL " "mechanisms" msgstr "RFC4512: 対応しているSASLメカニズム" #: -:- msgid "LDAP|Description|Attribute|telephoneNumber|RFC2256: Telephone Number" msgstr "RFC2256: 電話番号" #: -:- msgid "" "LDAP|Description|Attribute|teletexTerminalIdentifier|RFC2256: Teletex " "Terminal Identifier" msgstr "RFC2256: 文字多重放送端末識別子" #: -:- msgid "LDAP|Description|Attribute|telexNumber|RFC2256: Telex Number" msgstr "RFC2256: テレックス番号" #: -:- msgid "" "LDAP|Description|Attribute|title|RFC2256: title associated with the entity" msgstr "RFC2256: 実体に関連付けられているタイトル" #: -:- msgid "" "LDAP|Description|Attribute|uidNumber|RFC2307: An integer uniquely " "identifying a user in an administrative domain" msgstr "RFC2307: 管理上のドメインにいるユーザを一意に識別する整数値" #: -:- msgid "LDAP|Description|Attribute|uid|RFC4519: user identifier" msgstr "RFC4519: ユーザ識別子" #: -:- msgid "LDAP|Description|Attribute|uniqueIdentifier|RFC1274: unique identifer" msgstr "RFC1274: 一意な識別子" #: -:- msgid "" "LDAP|Description|Attribute|uniqueMember|RFC2256: unique member of a group" msgstr "RFC2256: 重複のないグループのメンバー" #: -:- msgid "" "LDAP|Description|Attribute|userCertificate|RFC2256: X.509 user certificate, " "use ;binary" msgstr "RFC2256: X.509ユーザ証明書。;binaryを使うこと" #: -:- msgid "LDAP|Description|Attribute|userClass|RFC1274: category of user" msgstr "RFC1274: ユーザの分類" #: -:- msgid "" "LDAP|Description|Attribute|userPKCS12|RFC2798: personal identity " "information, a PKCS #12 PFX" msgstr "RFC2798: 個人を識別する情報 (PKCS #12 PFX)" #: -:- msgid "LDAP|Description|Attribute|userPassword|RFC4519/2307: password of user" msgstr "RFC4519/2307: ユーザのパスワード" #: -:- msgid "" "LDAP|Description|Attribute|userSMIMECertificate|RFC2798: PKCS#7 SignedData " "used to support S/MIME" msgstr "RFC2798: S/MIMEをサポートするために使うPKCS#7署名済みデータ" #: -:- msgid "" "LDAP|Description|Attribute|vendorName|RFC3045: name of implementation vendor" msgstr "RFC3045: 実装ベンダーの名前" #: -:- msgid "" "LDAP|Description|Attribute|vendorVersion|RFC3045: version of implementation" msgstr "RFC3045: 実装のバージョン" #: -:- msgid "LDAP|Description|Attribute|x121Address|RFC2256: X.121 Address" msgstr "RFC2256: X.121アドレス" #: -:- msgid "" "LDAP|Description|Attribute|x500UniqueIdentifier|RFC2256: X.500 unique " "identifier" msgstr "RFC2256: X.500 一意の識別子" #: -:- msgid "" "LDAP|Description|ObjectClass|OpenLDAPdisplayableObject|OpenLDAP Displayable " "Object" msgstr "OpenLDAP: 表示可能なオブジェクト" #: -:- msgid "LDAP|Description|ObjectClass|OpenLDAPorg|OpenLDAP Organizational Object" msgstr "OpenLDAP: 組織オブジェクト" #: -:- msgid "" "LDAP|Description|ObjectClass|OpenLDAPou|OpenLDAP Organizational Unit Object" msgstr "OpenLDAP: 組織単位オブジェクト" #: -:- msgid "LDAP|Description|ObjectClass|OpenLDAPperson|OpenLDAP Person" msgstr "OpenLDAP: 人" #: -:- msgid "LDAP|Description|ObjectClass|OpenLDAProotDSE|OpenLDAP Root DSE object" msgstr "OpenLDAPのルートDSA特定エントリオブジェクト" #: -:- msgid "LDAP|Description|ObjectClass|alias|RFC4512: an alias" msgstr "RFC4512: 別名" #: -:- msgid "" "LDAP|Description|ObjectClass|applicationEntity|RFC2256: an application entity" msgstr "RFC2256: 応用実体" #: -:- msgid "" "LDAP|Description|ObjectClass|applicationProcess|RFC2256: an application " "process" msgstr "RFC2256: 応用プロセス" #: -:- msgid "" "LDAP|Description|ObjectClass|bootableDevice|A device with boot parameters" msgstr "起動パラメタ付きデバイス" #: -:- msgid "" "LDAP|Description|ObjectClass|certificationAuthority|RFC2256: a certificate " "authority" msgstr "RFC2256: 認証機関" #: -:- msgid "LDAP|Description|ObjectClass|country|RFC2256: a country" msgstr "RFC2256: 国" #: -:- msgid "" "LDAP|Description|ObjectClass|dSA|RFC2256: a directory system agent (a server)" msgstr "RFC2256: ディレクトリシステムエージェント(サーバ)" #: -:- msgid "LDAP|Description|ObjectClass|dcObject|RFC2247: domain component object" msgstr "RFC2247: ドメイン要素オブジェクト" #: -:- msgid "LDAP|Description|ObjectClass|deltaCRL|RFC2587: PKI user" msgstr "RFC2287: PKIユーザ" #: -:- msgid "LDAP|Description|ObjectClass|device|RFC2256: a device" msgstr "RFC2256: 装置" #: -:- msgid "" "LDAP|Description|ObjectClass|domainRelatedObject|RFC1274: an object related " "to an domain" msgstr "RFC1274: ドメインに関連したオブジェクト" #: -:- msgid "LDAP|Description|ObjectClass|dynamicObject|RFC2589: Dynamic Object" msgstr "RFC2589: 動的なオブジェクト" #: -:- msgid "" "LDAP|Description|ObjectClass|extensibleObject|RFC4512: extensible object" msgstr "RFC4512: 拡張可能なオブジェクト" #: -:- msgid "" "LDAP|Description|ObjectClass|groupOfNames|RFC2256: a group of names (DNs)" msgstr "RFC2256: 名前(DN)のグループ" #: -:- msgid "" "LDAP|Description|ObjectClass|groupOfUniqueNames|RFC2256: a group of unique " "names (DN and Unique Identifier)" msgstr "RFC2256: 一意な名前(DNと一意な識別子)のグループ" #: -:- msgid "LDAP|Description|ObjectClass|ieee802Device|A device with a MAC address" msgstr "MACアドレス付きの装置" #: -:- msgid "" "LDAP|Description|ObjectClass|inetOrgPerson|RFC2798: Internet Organizational " "Person" msgstr "RFC2798: インターネット組織の人" #: -:- msgid "LDAP|Description|ObjectClass|ipHost|Abstraction of a host, an IP device" msgstr "ホスト(IP装置)の抽象化" #: -:- msgid "LDAP|Description|ObjectClass|ipNetwork|Abstraction of an IP network" msgstr "IPネットワークの抽象化" #: -:- msgid "LDAP|Description|ObjectClass|ipProtocol|Abstraction of an IP protocol" msgstr "IPプロトコルの抽象化" #: -:- msgid "" "LDAP|Description|ObjectClass|ipService|Abstraction an Internet Protocol " "service" msgstr "IPサービスの抽象化" #: -:- msgid "" "LDAP|Description|ObjectClass|labeledURIObject|RFC2079: object that contains " "the URI attribute type" msgstr "RFC2079: URI属性種別を持ったオブジェクト" #: -:- msgid "LDAP|Description|ObjectClass|locality|RFC2256: a locality" msgstr "RFC2256: 地域" #: -:- msgid "LDAP|Description|ObjectClass|nisMap|A generic abstraction of a NIS map" msgstr "NISマップの一般的な抽象化" #: -:- msgid "LDAP|Description|ObjectClass|nisNetgroup|Abstraction of a netgroup" msgstr "ネットグループの抽象化" #: -:- msgid "LDAP|Description|ObjectClass|nisObject|An entry in a NIS map" msgstr "NISマップのエントリ" #: -:- msgid "" "LDAP|Description|ObjectClass|olcBackendConfig|OpenLDAP Backend-specific " "options" msgstr "OpenLDAPのバックエンド特有のオプション" #: -:- msgid "LDAP|Description|ObjectClass|olcBdbConfig|BDB backend configuration" msgstr "BDBバックエンドの設定" #: -:- msgid "LDAP|Description|ObjectClass|olcConfig|OpenLDAP configuration object" msgstr "OpenLDAPの設定オブジェクト" #: -:- msgid "" "LDAP|Description|ObjectClass|olcDatabaseConfig|OpenLDAP Database-specific " "options" msgstr "OpenLDAPのデータベース特有のオプション" #: -:- msgid "" "LDAP|Description|ObjectClass|olcFrontendConfig|OpenLDAP frontend " "configuration" msgstr "OpenLDAPのフロントエンドの設定" #: -:- msgid "" "LDAP|Description|ObjectClass|olcGlobal|OpenLDAP Global configuration options" msgstr "OpenLDAPのグローバルな設定オプション" #: -:- msgid "" "LDAP|Description|ObjectClass|olcIncludeFile|OpenLDAP configuration include " "file" msgstr "取り込むOpenLDAPの設定ファイル" #: -:- msgid "LDAP|Description|ObjectClass|olcLdifConfig|LDIF backend configuration" msgstr "LDIFバックエンドの設定" #: -:- msgid "LDAP|Description|ObjectClass|olcModuleList|OpenLDAP dynamic module info" msgstr "OpenLDAPの動的モジュールの情報" #: -:- msgid "" "LDAP|Description|ObjectClass|olcOverlayConfig|OpenLDAP Overlay-specific " "options" msgstr "OpenLDAPのオーバレイ特有のオプション" #: -:- msgid "LDAP|Description|ObjectClass|olcSchemaConfig|OpenLDAP schema object" msgstr "OpenLDAPのスキーマオブジェクト" #: -:- msgid "LDAP|Description|ObjectClass|oncRpc|Abstraction of an ONC/RPC binding" msgstr "ONC RPCバインディングの抽象化" #: -:- msgid "" "LDAP|Description|ObjectClass|organizationalPerson|RFC2256: an organizational " "person" msgstr "RFC2256: 組織の人" #: -:- msgid "" "LDAP|Description|ObjectClass|organizationalRole|RFC2256: an organizational " "role" msgstr "RFC2256: 組織の役割" #: -:- msgid "" "LDAP|Description|ObjectClass|organizationalUnit|RFC2256: an organizational " "unit" msgstr "RFC2256: 組織の単位" #: -:- msgid "LDAP|Description|ObjectClass|organization|RFC2256: an organization" msgstr "RFC2256: 組織" #: -:- msgid "LDAP|Description|ObjectClass|person|RFC2256: a person" msgstr "RFC2256: 人" #: -:- msgid "LDAP|Description|ObjectClass|pkiCA|RFC2587: PKI certificate authority" msgstr "RFC2287: PKI認証機関" #: -:- msgid "LDAP|Description|ObjectClass|pkiUser|RFC2587: a PKI user" msgstr "RFC2287: PKIユーザ" #: -:- msgid "" "LDAP|Description|ObjectClass|posixAccount|Abstraction of an account with " "POSIX attributes" msgstr "POSIX属性をもつアカウントの抽象化" #: -:- msgid "" "LDAP|Description|ObjectClass|posixGroup|Abstraction of a group of accounts" msgstr "アカウントのグループの抽象化" #: -:- msgid "" "LDAP|Description|ObjectClass|referral|namedref: named subordinate referral" msgstr "名前付き参照: 名前の付いた下位の照会" #: -:- msgid "" "LDAP|Description|ObjectClass|residentialPerson|RFC2256: an residential person" msgstr "RFC2256: 居住者" #: -:- msgid "" "LDAP|Description|ObjectClass|sambaConfigOption|Samba Configuration Option" msgstr "Sambaの設定オプション" #: -:- msgid "LDAP|Description|ObjectClass|sambaConfig|Samba Configuration Section" msgstr "Sambaoの設定セクション" #: -:- msgid "LDAP|Description|ObjectClass|sambaDomain|Samba Domain Information" msgstr "Sambaのドメイン情報" #: -:- msgid "LDAP|Description|ObjectClass|sambaGroupMapping|Samba Group Mapping" msgstr "Sambaのグループ写像" #: -:- msgid "" "LDAP|Description|ObjectClass|sambaIdmapEntry|Mapping from a SID to an ID" msgstr "SIDからIDへの写像" #: -:- msgid "" "LDAP|Description|ObjectClass|sambaSamAccount|Samba 3.0 Auxilary SAM Account" msgstr "Samba 3.0の補助的なSAMアカウント" #: -:- msgid "LDAP|Description|ObjectClass|sambaShare|Samba Share Section" msgstr "Sambaの共有セクション" #: -:- msgid "LDAP|Description|ObjectClass|sambaSidEntry|Structural Class for a SID" msgstr "SIDの構造的なクラス" #: -:- msgid "LDAP|Description|ObjectClass|sambaTrustPassword|Samba Trust Password" msgstr "Sambaの信用パスワード" #: -:- msgid "" "LDAP|Description|ObjectClass|sambaUnixIdPool|Pool for allocating UNIX uids/" "gids" msgstr "UNIXのUID/GIDを割り当てるためのプール" #: -:- msgid "" "LDAP|Description|ObjectClass|shadowAccount|Additional attributes for shadow " "passwords" msgstr "シャドーパスワード用追加属性" #: -:- msgid "" "LDAP|Description|ObjectClass|simpleSecurityObject|RFC1274: simple security " "object" msgstr "RFC1274: 簡素な安全性を持つオブジェクト" #: -:- msgid "" "LDAP|Description|ObjectClass|strongAuthenticationUser|RFC2256: a strong " "authentication user" msgstr "RFC2256: 強力な認証ユーザ" #: -:- msgid "LDAP|Description|ObjectClass|subentry|RFC3672: subentry" msgstr "RFC3672: 国" #: -:- msgid "" "LDAP|Description|ObjectClass|subschema|RFC4512: controlling subschema (sub)" "entry" msgstr "RFC4512: 制御しているサブスキーマエントリ" #: -:- msgid "LDAP|Description|ObjectClass|top|top of the superclass chain" msgstr "スーパクラス連鎖の最上位" #: -:- msgid "LDAP|Description|ObjectClass|uidObject|RFC2377: uid object" msgstr "RFC2377: UIDオブジェクト" #: -:- msgid "" "LDAP|Description|ObjectClass|userSecurityInformation|RFC2256: a user " "security information" msgstr "RFC2256: ユーザセキュリティ情報" #: -:- msgid "LDAP|Description|Syntax|1.2.36.79672281.1.5.0|RDN" msgstr "相対識別名(RDN)" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.1.1.0.0|RFC2307 NIS Netgroup Triple" msgstr "RFC2307: NISネットグループのトリプル" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.1.1.0.1|RFC2307 Boot Parameter" msgstr "RFC2307: 起動パラメータ" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.1.16.1|UUID" msgstr "UUID" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.10|Certificate Pair" msgstr "相互認証組(Certificate Pair)" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.11|Country String" msgstr "国コード" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.12|Distinguished Name" msgstr "識別名(DN)" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.14|Delivery Method" msgstr "配送方法" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.15|Directory String" msgstr "ディレクトリ文字列(UTF-8形式)" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.22|Facsimile Telephone " "Number" msgstr "FAX番号" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.24|Generalized Time" msgstr "一般化された時刻" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.26|IA5 String" msgstr "IA5文字列(任意の文字列)" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.27|Integer" msgstr "整数" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.28|JPEG" msgstr "JPEG" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.34|Name And Optional UID" msgstr "名前と省略可能なUID" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.36|Numeric String" msgstr "数字" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.38|OID" msgstr "オブジェクトID(OID)" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.39|Other Mailbox" msgstr "他のメールボックス" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.40|Octet String" msgstr "8進数文字列" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.41|Postal Address" msgstr "郵便番号" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.44|Printable String" msgstr "印字可能な文字列" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.45|SubtreeSpecification" msgstr "サブツリー仕様" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.49|Supported Algorithm" msgstr "対応しているアルゴリズム" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.4|Audio" msgstr "音声" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.50|Telephone Number" msgstr "電話番号" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.52|Telex Number" msgstr "テレックス番号" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.5|Binary" msgstr "バイナリ" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.6|Bit String" msgstr "2進数文字列" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.7|Boolean" msgstr "真偽値" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.8|Certificate" msgstr "証明書" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.9|Certificate List" msgstr "証明書一覧" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.4203.666.11.10.2.1|X.509 " "AttributeCertificate" msgstr "X.509属性証明書" #: -:- msgid "LDAP|ObjectClass|LDAProotDSE" msgstr "LDAPルートDSE(LDAProotDSE)" #: -:- msgid "LDAP|ObjectClass|OpenLDAPdisplayableObject" msgstr "OpenLDAP: 表示可能なオブジェクト(OpenLDAPdisplayableObject)" #: -:- msgid "LDAP|ObjectClass|OpenLDAPorg" msgstr "OpenLDAP: 組織(OpenLDAPorg)" #: -:- msgid "LDAP|ObjectClass|OpenLDAPou" msgstr "OpenLDAP: 組織単位(OpenLDAPou)" #: -:- msgid "LDAP|ObjectClass|OpenLDAPperson" msgstr "OpenLDAP: 人(OpenLDAPperson)" #: -:- msgid "LDAP|ObjectClass|OpenLDAProotDSE" msgstr "OpenLDAP: ルートDSE(OpenLDAProotDSE)" #: -:- msgid "LDAP|ObjectClass|RFC822localPart" msgstr "RFC822: ローカルパート(RFC822localPart)" #: -:- msgid "LDAP|ObjectClass|account" msgstr "アカウント(account)" #: -:- msgid "LDAP|ObjectClass|alias" msgstr "別名(alias)" #: -:- msgid "LDAP|ObjectClass|applicationEntity" msgstr "応用実体(applicationEntity)" #: -:- msgid "LDAP|ObjectClass|applicationProcess" msgstr "応用プロセス(applicationProcess)" #: -:- msgid "LDAP|ObjectClass|bootableDevice" msgstr "起動可能デバイス(booatbleDevice)" #: -:- msgid "LDAP|ObjectClass|cRLDistributionPoint" msgstr "CRL配布点(cRLDistributionPoint)" #: -:- msgid "LDAP|ObjectClass|certificationAuthority" msgstr "認証機関(certificationAuthority)" #: -:- msgid "LDAP|ObjectClass|certificationAuthority-V2" msgstr "認証機関-V2(certificationAuthority-V2)" #: -:- msgid "LDAP|ObjectClass|country" msgstr "国(country)" #: -:- msgid "LDAP|ObjectClass|dNSDomain" msgstr "DNSドメイン(dNSDomain)" #: -:- msgid "LDAP|ObjectClass|dSA" msgstr "DSA(dSA)" #: -:- msgid "LDAP|ObjectClass|dcObject" msgstr "ドメイン要素オブジェクト(dcObject)" #: -:- msgid "LDAP|ObjectClass|deltaCRL" msgstr "差分CRL(deltaCRL)" #: -:- msgid "LDAP|ObjectClass|device" msgstr "デバイス(device)" #: -:- msgid "LDAP|ObjectClass|dmd" msgstr "ディレクトリ管理ドメイン(dmd)" #: -:- msgid "LDAP|ObjectClass|document" msgstr "文書(document)" #: -:- msgid "LDAP|ObjectClass|documentSeries" msgstr "文書シリーズ(documentSeries)" #: -:- msgid "LDAP|ObjectClass|domain" msgstr "ドメイン(domain)" #: -:- msgid "LDAP|ObjectClass|domainRelatedObject" msgstr "ドメイン関連オブジェクト(domainRelatedObject)" #: -:- msgid "LDAP|ObjectClass|dynamicObject" msgstr "動的なオブジェクト(dynamicObject)" #: -:- msgid "LDAP|ObjectClass|extensibleObject" msgstr "拡張可能なオブジェクト(extensibleObject)" #: -:- msgid "LDAP|ObjectClass|friendlyCountry" msgstr "友好国(friendlyCountry)" #: -:- msgid "LDAP|ObjectClass|groupOfNames" msgstr "名前のグループ(groupOfNames)" #: -:- msgid "LDAP|ObjectClass|groupOfUniqueNames" msgstr "一意な名前のグループ(groupOfUniqueNames)" #: -:- msgid "LDAP|ObjectClass|ieee802Device" msgstr "IEEE802規格のデバイス(ieee802Device)" #: -:- msgid "LDAP|ObjectClass|inetOrgPerson" msgstr "インターネット組織の人(inetOrgPerson)" #: -:- msgid "LDAP|ObjectClass|ipHost" msgstr "IPホスト(ipHost)" #: -:- msgid "LDAP|ObjectClass|ipNetwork" msgstr "IPネットワーク(ipNetwork)" #: -:- msgid "LDAP|ObjectClass|ipProtocol" msgstr "IPプロトコル(ipProtocol)" #: -:- msgid "LDAP|ObjectClass|ipService" msgstr "IPサービス(ipService)" #: -:- msgid "LDAP|ObjectClass|labeledURIObject" msgstr "ラベル付きのURIオブジェクト(labeledURIObject)" #: -:- msgid "LDAP|ObjectClass|locality" msgstr "地域(locality)" #: -:- msgid "LDAP|ObjectClass|newPilotPerson" msgstr "新しい試験的な人(newPilotPerson)" #: -:- msgid "LDAP|ObjectClass|nisMap" msgstr "NISマップ(nisMap)" #: -:- msgid "LDAP|ObjectClass|nisNetgroup" msgstr "NISネットグループ(nisNetgroup)" #: -:- msgid "LDAP|ObjectClass|nisObject" msgstr "NISオブジェクト(nisObject)" #: -:- msgid "LDAP|ObjectClass|olcBackendConfig" msgstr "OpenLDAP設定: バックエンド設定(olcBackendConfig)" #: -:- msgid "LDAP|ObjectClass|olcBdbConfig" msgstr "OpenLDAP設定: BDB設定(olcBdbConfig)" #: -:- msgid "LDAP|ObjectClass|olcConfig" msgstr "OpenLDAP設定: 設定(olcConfig)" #: -:- msgid "LDAP|ObjectClass|olcDatabaseConfig" msgstr "OpenLDAP設定: データベース設定(olcDatabaseConfig)" #: -:- msgid "LDAP|ObjectClass|olcFrontendConfig" msgstr "OpenLDAP設定: フロントエンド設定(olcFrontendConfig)" #: -:- msgid "LDAP|ObjectClass|olcGlobal" msgstr "OpenLDAP設定: グローバル(olcGlobal)" #: -:- msgid "LDAP|ObjectClass|olcIncludeFile" msgstr "OpenLDAP設定: ファイル取り込み(olcIncludeFile)" #: -:- msgid "LDAP|ObjectClass|olcLdifConfig" msgstr "OpenLDAP設定: LDIF設定(olcLdifConfig)" #: -:- msgid "LDAP|ObjectClass|olcModuleList" msgstr "OpenLDAP設定: モジュール一覧(olcModuleList)" #: -:- msgid "LDAP|ObjectClass|olcOverlayConfig" msgstr "OpenLDAP設定: オーバレイ設定(olcOverlayConfig)" #: -:- msgid "LDAP|ObjectClass|olcSchemaConfig" msgstr "OpenLDAP設定: スキーマ設定(olcSchemaConfig)" #: -:- msgid "LDAP|ObjectClass|oncRpc" msgstr "ONC RPC(oncRpc)" #: -:- msgid "LDAP|ObjectClass|organization" msgstr "組織(organization)" #: -:- msgid "LDAP|ObjectClass|organizationalPerson" msgstr "組織の人(organizationalPerson)" #: -:- msgid "LDAP|ObjectClass|organizationalRole" msgstr "組織上の役割(organizationalRole)" #: -:- msgid "LDAP|ObjectClass|organizationalUnit" msgstr "組織の単位(organizationalUnit)" #: -:- msgid "LDAP|ObjectClass|person" msgstr "人(person)" #: -:- msgid "LDAP|ObjectClass|pilotDSA" msgstr "試験的なDSA(pilotDSA)" #: -:- msgid "LDAP|ObjectClass|pilotOrganization" msgstr "試験的な組織(pilotOrganization)" #: -:- msgid "LDAP|ObjectClass|pilotPerson" msgstr "試験的な人(pilotPerson)" #: -:- msgid "LDAP|ObjectClass|pkiCA" msgstr "PKI CA(pkiCA)" #: -:- msgid "LDAP|ObjectClass|pkiUser" msgstr "PKIユーザ(pkiUser)" #: -:- msgid "LDAP|ObjectClass|posixAccount" msgstr "POSIXアカウント(posixAccount)" #: -:- msgid "LDAP|ObjectClass|posixGroup" msgstr "POSIXグループ(posixGroup)" #: -:- msgid "LDAP|ObjectClass|qualityLabelledData" msgstr "品質がラベル付けされたデータ(qualityLabelledData)" #: -:- msgid "LDAP|ObjectClass|referral" msgstr "照会(referral)" #: -:- msgid "LDAP|ObjectClass|residentialPerson" msgstr "居住者(residentialPerson)" #: -:- msgid "LDAP|ObjectClass|room" msgstr "部屋(room)" #: -:- msgid "LDAP|ObjectClass|sambaConfig" msgstr "Samba: 設定(sambaConfig)" #: -:- msgid "LDAP|ObjectClass|sambaConfigOption" msgstr "Samba: 設定オプション(sambaConfigOption)" #: -:- msgid "LDAP|ObjectClass|sambaDomain" msgstr "Samba: ドメイン(sambaDomain)" #: -:- msgid "LDAP|ObjectClass|sambaGroupMapping" msgstr "Samba: グループ写像(sambaGroupMapping)" #: -:- msgid "LDAP|ObjectClass|sambaIdmapEntry" msgstr "Samba: ID写像エントリ(sambaIdmapEntry)" #: -:- msgid "LDAP|ObjectClass|sambaSamAccount" msgstr "Samba: SAMアカウント(sambaSamAccount)" #: -:- msgid "LDAP|ObjectClass|sambaShare" msgstr "Samba: 共有(sambaShare)" #: -:- msgid "LDAP|ObjectClass|sambaSidEntry" msgstr "Samba: SIDエントリ(sambaSidEntry)" #: -:- msgid "LDAP|ObjectClass|sambaTrustPassword" msgstr "Samba: 信用パスワード(sambaTrustPassword)" #: -:- msgid "LDAP|ObjectClass|sambaUnixIdPool" msgstr "Samba: UNIX IDプール(sambaUnixIdPool)" #: -:- msgid "LDAP|ObjectClass|shadowAccount" msgstr "シャドーアカウント(shadowAccount)" #: -:- msgid "LDAP|ObjectClass|simpleSecurityObject" msgstr "簡素なセキュリティオブジェクト(simpleSecurityObject)" #: -:- msgid "LDAP|ObjectClass|strongAuthenticationUser" msgstr "強力な認証ユーザ(strongAuthenticationUser)" #: -:- msgid "LDAP|ObjectClass|subentry" msgstr "サブエントリ(subentry)" #: -:- msgid "LDAP|ObjectClass|subschema" msgstr "サブスキーマ(subschema)" #: -:- msgid "LDAP|ObjectClass|top" msgstr "トップ(top)" #: -:- msgid "LDAP|ObjectClass|uidObject" msgstr "UIDオブジェクト(uidObject)" #: -:- msgid "LDAP|ObjectClass|userSecurityInformation" msgstr "ユーザセキュリティ情報(userSecurityInformation)" #: -:- msgid "LDAP|Syntax|1.2.36.79672281.1.5.0" msgstr "RDN(1.2.36.79672281.1.5.0)" #: -:- msgid "LDAP|Syntax|1.3.6.1.1.1.0.0" msgstr "NISネットグループのトリプル(1.3.6.1.1.1.0.0)" #: -:- msgid "LDAP|Syntax|1.3.6.1.1.1.0.1" msgstr "起動パラメータ(1.3.6.1.1.1.0.1)" #: -:- msgid "LDAP|Syntax|1.3.6.1.1.16.1" msgstr "UUID(1.3.6.1.1.16.1)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.10" msgstr "相互認証組(1.3.6.1.4.1.1466.115.121.1.10)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.11" msgstr "国コード(1.3.6.1.4.1.1466.115.121.1.11)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.12" msgstr "DN(1.3.6.1.4.1.1466.115.121.1.12)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.14" msgstr "配送方法(1.3.6.1.4.1.1466.115.121.1.14)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.15" msgstr "ディレクトリ文字列(1.3.6.1.4.1.1466.115.121.1.15)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.22" msgstr "FAX番号(1.3.6.1.4.1.1466.115.121.1.22)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.24" msgstr "一般化された時刻(1.3.6.1.4.1.1466.115.121.1.24)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.26" msgstr "IA5文字列(1.3.6.1.4.1.1466.115.121.1.26)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.27" msgstr "整数(1.3.6.1.4.1.1466.115.121.1.27)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.28" msgstr "JPEG(1.3.6.1.4.1.1466.115.121.1.28)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.34" msgstr "名前と省略可能なOID(1.3.6.1.4.1.1466.115.121.1.34)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.36" msgstr "数字(1.3.6.1.4.1.1466.115.121.1.36)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.38" msgstr "OID(1.3.6.1.4.1.1466.115.121.1.38)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.39" msgstr "他のメールボックス(1.3.6.1.4.1.1466.115.121.1.39)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.4" msgstr "音声(1.3.6.1.4.1.1466.115.121.1.4)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.40" msgstr "8進数文字列(1.3.6.1.4.1.1466.115.121.1.40)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.41" msgstr "郵便番号(1.3.6.1.4.1.1466.115.121.1.41)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.44" msgstr "印字可能な文字列(1.3.6.1.4.1.1466.115.121.1.44)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.45" msgstr "サブツリー仕様(1.3.6.1.4.1.1466.115.121.1.45)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.49" msgstr "対応しているアルゴリズム(1.3.6.1.4.1.1466.115.121.1.49)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.5" msgstr "バイナリ(1.3.6.1.4.1.1466.115.121.1.5)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.50" msgstr "電話番号(1.3.6.1.4.1.1466.115.121.1.50)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.52" msgstr "テレックス番号(1.3.6.1.4.1.1466.115.121.1.52)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.6" msgstr "2進数文字列(1.3.6.1.4.1.1466.115.121.1.6)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.7" msgstr "真偽値(1.3.6.1.4.1.1466.115.121.1.7)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.8" msgstr "証明書(1.3.6.1.4.1.1466.115.121.1.8)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.9" msgstr "証明書一覧(1.3.6.1.4.1.1466.115.121.1.9)" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.4203.666.11.10.2.1" msgstr "X.509属性証明書(1.3.6.1.4.1.4203.666.11.10.2.1)" #: lib/active_ldap/object_class.rb:53 msgid "Value in objectClass array is not a String: %s" msgstr "objectClassの配列の中身がStringではありません: %s" #: lib/active_ldap/object_class.rb:67 msgid "unknown objectClass in LDAP server: %s" msgstr "LDAPサーバが知らないobjectClassです: %s" #: lib/active_ldap/object_class.rb:85 msgid "Can't remove required objectClass: %s" msgstr "必須のobjectClassは削除できません: %s" #: lib/active_ldap/adapter/jndi.rb:105 lib/active_ldap/adapter/ldap.rb:203 #: lib/active_ldap/adapter/net_ldap.rb:155 msgid "%s is not one of the available connect methods: %s" msgstr "%sは有効な接続方法ではありません: %s" #: lib/active_ldap/adapter/jndi.rb:118 lib/active_ldap/adapter/ldap.rb:216 #: lib/active_ldap/adapter/net_ldap.rb:168 msgid "%s is not one of the available LDAP scope: %s" msgstr "%sは有効なLDAPスコープではありません: %s" #: lib/active_ldap/adapter/jndi.rb:176 lib/active_ldap/adapter/ldap.rb:280 #: lib/active_ldap/adapter/net_ldap.rb:290 msgid "unknown type: %s" msgstr "未知の種類です: %s" #: lib/active_ldap/adapter/ldap.rb:108 msgid "No matches: filter: %s: attributes: %s" msgstr "マッチしませんでした: フィルタ: %s: 属性: %s" #: lib/active_ldap/adapter/ldap.rb:162 msgid "modify RDN with new superior" msgstr "異なるツリー上のRDNへ変更" #: lib/active_ldap/adapter/net_ldap.rb:211 msgid "unsupported qops: %s" msgstr "対応していないqopsです: %s" #: lib/active_ldap/adapter/base.rb:84 msgid "Bound to %s by SASL as %s" msgstr "%sに%sとしてSASLで接続しました" #: lib/active_ldap/adapter/base.rb:86 msgid "Bound to %s by simple as %s" msgstr "%sに%sとしてシンプル認証で接続しました" #: lib/active_ldap/adapter/base.rb:88 msgid "Bound to %s as anonymous" msgstr "%sに匿名ユーザとして接続しました" #: lib/active_ldap/adapter/base.rb:91 msgid "All authentication methods for %s exhausted." msgstr "%sへのすべての認証方法が失敗しました。" #: lib/active_ldap/adapter/base.rb:171 msgid "Ignore error %s(%s): filter %s: attributes: %s" msgstr "エラー%s(%s)を無視します: フィルタ %s: 属性: %s" #: lib/active_ldap/adapter/base.rb:187 lib/active_ldap/adapter/base.rb:206 #: lib/active_ldap/adapter/base.rb:208 lib/active_ldap/adapter/base.rb:210 #: lib/active_ldap/adapter/base.rb:212 lib/active_ldap/adapter/base.rb:222 #: lib/active_ldap/adapter/base.rb:228 msgid "%s: %s" msgstr "%s: %s" #: lib/active_ldap/adapter/base.rb:192 lib/active_ldap/adapter/base.rb:202 msgid "No such entry: %s" msgstr "そのようなエントリはありません: %s" #: lib/active_ldap/adapter/base.rb:293 msgid "password_block not nil or Proc object. Ignoring." msgstr "password_blockがnilでもProcでもありません。無視します。" #: lib/active_ldap/adapter/base.rb:314 msgid "Requested action timed out." msgstr "要求したアクションがタイムアウトしました。" #: lib/active_ldap/adapter/base.rb:355 msgid "Skip simple bind with empty password." msgstr "空パスワードでのシンプル認証を行いませんでした。" #: lib/active_ldap/adapter/base.rb:359 msgid "Can't use empty password for simple bind." msgstr "シンプル認証では空のパスワードを使うことはできません。" #: lib/active_ldap/adapter/base.rb:551 msgid "invalid logical operator: %s: available operators: %s" msgstr "不正な論理演算子です: %s: 有効な演算子: %s\n" #: lib/active_ldap/adapter/base.rb:566 msgid "Attempting to reconnect" msgstr "再接続を試みています" #: lib/active_ldap/adapter/base.rb:579 msgid "" "Reconnect to server failed: %s: %s\n" "Reconnect to server failed backtrace:\n" "%s" msgstr "" "サーバへの再接続が失敗しました: %s: %s\n" "サーバへの再接続失敗時のバックトレース:\n" "%s" #: lib/active_ldap/adapter/base.rb:589 msgid "Giving up trying to reconnect to LDAP server." msgstr "LDAPサーバへの再接続を諦めました。" #: lib/active_ldap/acts/tree.rb:66 msgid "parent must be an entry or parent DN: %s" msgstr "親はエントリかDNでなければいけません: %s" #: lib/active_ldap/operations.rb:49 msgid ":ldap_scope search option is deprecated. Use :scope instead." msgstr "" ":ldap_search検索オプションは廃止予定です。代わりに:scopeを使ってください。" #: lib/active_ldap/operations.rb:258 msgid "Invalid order: %s" msgstr "不正な順序です: %s" #: lib/active_ldap/operations.rb:294 msgid "Couldn't find %s without a DN" msgstr "DNがないため%sが見つかりません" #: lib/active_ldap/operations.rb:316 msgid "Couldn't find %s: DN: %s: filter: %s" msgstr "%sが見つかりません: DN: %s: フィルタ: %s" #: lib/active_ldap/operations.rb:319 msgid "Couldn't find %s: DN: %s" msgstr "%sが見つかりません: DN: %s" #: lib/active_ldap/operations.rb:346 msgid "Couldn't find all %s: DNs (%s): filter: %s" msgstr "すべての%sを見つけられませんでした: DN (%s): フィルタ: %s" #: lib/active_ldap/operations.rb:349 msgid "Couldn't find all %s: DNs (%s)" msgstr "すべての%sを見つけられませんでした: DN (%s)" #: lib/active_ldap/operations.rb:504 msgid "Failed to delete LDAP entry: <%s>: %s" msgstr "LDAPエントリの削除に失敗しました: <%s>: %s" #: lib/active_ldap/associations.rb:68 msgid "" ":foreign_key belongs_to(:many) option is deprecated since 1.1.0. Use :" "primary_key instead." msgstr "" "1.1.0からbelongs_to(:many)の:foreign_keyオプションは非推奨になりました。代わ" "りに:primary_keyを使ってください。" #: lib/active_ldap/associations.rb:136 msgid "" ":primary_key and :foreign_key has_many options are inverted their mean since " "1.1.0. Please invert them." msgstr "" "1.1.0からhas_manyの:primary_keyと:foreign_keyオプションの意味が反対になりまし" "た。オプションの値を入れかえてください。" #: lib/active_ldap/ldif.rb:396 msgid "version spec is missing" msgstr "バージョン指定がありません" #: lib/active_ldap/ldif.rb:400 msgid "version number is missing" msgstr "バージョン番号がありません" #: lib/active_ldap/ldif.rb:404 msgid "unsupported version: %d" msgstr "対応していないバージョンです: %d" #: lib/active_ldap/ldif.rb:408 msgid "separator is missing" msgstr "分離記号(改行)がありません" #: lib/active_ldap/ldif.rb:412 msgid "'dn:' is missing" msgstr "'dn:'がありません" #: lib/active_ldap/ldif.rb:416 msgid "DN is missing" msgstr "DNがありません" #: lib/active_ldap/ldif.rb:420 msgid "DN is invalid: %s: %s" msgstr "不正なDNです: %s: %s" #: lib/active_ldap/ldif.rb:424 msgid "DN has an invalid character: %s" msgstr "DNは不正な文字を含んでいます: %s" #: lib/active_ldap/ldif.rb:428 lib/active_ldap/distinguished_name.rb:144 msgid "attribute type is missing" msgstr "属性の種類がありません" #: lib/active_ldap/ldif.rb:432 msgid "option is missing" msgstr "オプションがありません" #: lib/active_ldap/ldif.rb:436 msgid "':' is missing" msgstr "':'がありません" #: lib/active_ldap/ldif.rb:440 msgid "URI is invalid: %s: %s" msgstr "不正なURIです: %s: %s" #: lib/active_ldap/ldif.rb:444 msgid "'-' is missing" msgstr "'-'がありません" #: lib/active_ldap/ldif.rb:448 msgid "unknown change type: %s" msgstr "未知の変更型です: %s" #: lib/active_ldap/ldif.rb:452 msgid "change type is missing" msgstr "変更型がありません" #: lib/active_ldap/ldif.rb:456 msgid "control type is missing" msgstr "制御型がありません" #: lib/active_ldap/ldif.rb:460 msgid "criticality is missing" msgstr "臨界指定がありません" #: lib/active_ldap/ldif.rb:464 msgid "change type value is missing" msgstr "変更型の値がありません" #: lib/active_ldap/ldif.rb:468 msgid "attribute spec is missing" msgstr "属性指定がありません" #: lib/active_ldap/ldif.rb:472 msgid "'newrdn:' is missing" msgstr "'newrdn:'がありません" #: lib/active_ldap/ldif.rb:476 msgid "new RDN value is missing" msgstr "新しいRDNの値がありません" #: lib/active_ldap/ldif.rb:480 msgid "'deleteoldrdn:' is missing" msgstr "deleteoldrdn:'がありません" #: lib/active_ldap/ldif.rb:484 msgid "delete old RDN value is missing" msgstr "古いRDNを削除するかどうかの指定値がありません" #: lib/active_ldap/ldif.rb:488 msgid "new superior value is missing" msgstr "新しい親エントリの値がありません" #: lib/active_ldap/ldif.rb:492 msgid "unknown modify type: %s" msgstr "未知の変更種類です: %s" #: lib/active_ldap/ldif.rb:765 msgid "invalid criticality value: %s" msgstr "不正な臨界指定値です: %s" #: lib/active_ldap/ldif.rb:808 msgid "invalid deleteoldrdn value: %s" msgstr "不正なdeleteoldrdn値です: %s" #: lib/active_ldap/distinguished_name.rb:136 msgid "name component is missing" msgstr "名前要素がありません" #: lib/active_ldap/distinguished_name.rb:140 msgid "relative distinguished name (RDN) is missing" msgstr "相対識別名(RDN)がありません" #: lib/active_ldap/distinguished_name.rb:148 msgid "attribute value is missing" msgstr "属性の値がありません" #: lib/active_ldap/distinguished_name.rb:152 msgid "found unmatched quotation" msgstr "未対応の引用符が見つかりました" #: lib/active_ldap/distinguished_name.rb:188 msgid "%s isn't sub DN of %s" msgstr "%sは%sのサブDNではありません" #: lib/active_ldap/validations.rb:97 msgid "is duplicated: %s" msgstr "が重複しています: %s" #: lib/active_ldap/validations.rb:108 msgid "is invalid: %s" msgstr "が不正です: %s" #: lib/active_ldap/validations.rb:112 msgid "isn't set: %s" msgstr "が設定されていません: %s" #: lib/active_ldap/validations.rb:134 msgid "has excluded value: %s" msgid_plural "has excluded values: %s" msgstr[0] "に除外した値があります: %s" msgstr[1] "に除外した値があります: %s" #: lib/active_ldap/validations.rb:169 msgid "is required attribute by objectClass '%s'" msgstr "はobjectClass'%s'の必須の属性です" #: lib/active_ldap/validations.rb:171 msgid "is required attribute by objectClass '%s': aliases: %s" msgstr "はobjectClass'%s'の必須の属性です: 別名: %s" #: lib/active_ldap/validations.rb:195 msgid "" msgstr "<バイナリ値>" #: lib/active_ldap/validations.rb:203 msgid "(%s) has invalid format: %s: required syntax: %s: %s" msgstr "(%s)は不正な書式です: %s: 要求されている構文: %s: %s" #: lib/active_ldap/validations.rb:205 msgid "has invalid format: %s: required syntax: %s: %s" msgstr "は不正な書式です: %s: 要求されている構文: %s: %s" #: lib/active_ldap/command.rb:16 msgid "Common options:" msgstr "共通のオプション" #: lib/active_ldap/command.rb:19 msgid "Specify configuration file written as YAML" msgstr "YAMLで記述した設定ファイルを指定してください" #: lib/active_ldap/command.rb:26 msgid "Show this message" msgstr "このメッセージを表示します" #: lib/active_ldap/command.rb:31 msgid "Show version" msgstr "バージョンを表示します" #: lib/active_ldap/base.rb:53 msgid "" "ActiveLdap::ConnectionNotEstablished has been deprecated since 1.1.0. Please " "use ActiveLdap::ConnectionNotSetup instead." msgstr "" "1.1.0からActiveLdap::ConnectionNotEstablishedは非推奨になりました。代わりに" "ActiveLdap::ConnectionNotSetupを使ってください。" #: lib/active_ldap/base.rb:131 msgid "invalid distinguished name (DN) to parse: %s" msgstr "構文解析できない不正な識別名(DN)です: %s" #: lib/active_ldap/base.rb:141 msgid "%s is invalid distinguished name (DN): %s" msgstr "%sは不正な識別名(DN)です: %s" #: lib/active_ldap/base.rb:143 msgid "%s is invalid distinguished name (DN)" msgstr "%sは不正な識別名(DN)です" #: lib/active_ldap/base.rb:161 msgid "invalid LDIF: %s:" msgstr "不正なLDIFです: %s:" #: lib/active_ldap/base.rb:163 msgid "invalid LDIF:" msgstr "不正なLDIFです:" #: lib/active_ldap/base.rb:241 msgid "LDAP configuration specifies nonexistent %s adapter" msgstr "LDAPの設定が存在しない%sアダプタが指定しています" #: lib/active_ldap/base.rb:249 msgid "%s is unknown attribute" msgstr "%sは未知の属性です" #: lib/active_ldap/base.rb:266 msgid "not implemented: %s" msgstr "未実装です: %s" #: lib/active_ldap/base.rb:382 msgid "" "ActiveLdap::Base.establish_connection has been deprecated since 1.1.0. " "Please use ActiveLdap::Base.setup_connection instead." msgstr "" "1.1.0からActiveLdap::Base.establish_connectionは非推奨になりました。代わりに" "ActiveLdap::Base.setup_connectionを使ってください。" #: lib/active_ldap/base.rb:463 msgid "scope '%s' must be a Symbol" msgstr "スコープ'%s'はシンボルでなければいけません" #: lib/active_ldap/base.rb:514 msgid "%s doesn't belong in a hierarchy descending from ActiveLdap" msgstr "%sはActiveLdapの子孫ではありません。" #: lib/active_ldap/base.rb:669 msgid "" "'%s' must be either nil, DN value as ActiveLdap::DN, String or Array or " "attributes as Hash" msgstr "" "'%s'はnil、ActiveLdap::DNあるいはStringによるDN、DNの配列、Hashによる属性のど" "れかでなければいけません" #: lib/active_ldap/base.rb:799 msgid "entry %s can't be saved" msgstr "エントリ%sを保存できません" #: lib/active_ldap/base.rb:832 lib/active_ldap/base.rb:843 msgid "wrong number of arguments (%d for 1)" msgstr "引数の数が違います。(1つの引数なのに%d個指定しました)" #: lib/active_ldap/base.rb:964 msgid "Can't find DN '%s' to reload" msgstr "再読み込みするDN '%s'が見つかりません" #: lib/active_ldap/base.rb:1369 msgid "%s's DN attribute (%s) isn't set" msgstr "%sのDN属性(%s)が設定されていません" #: lib/active_ldap/attributes.rb:80 msgid "The first argument, name, must not be nil. Please report this as a bug!" msgstr "" "最初の引数nameがnilになるはずがあってはいけません。バグとして報告してくださ" "い!" #: lib/active_ldap/schema.rb:52 msgid "Unknown schema group: %s" msgstr "未知のスキーマグループです: %s" #: lib/active_ldap/schema.rb:547 msgid "Attribute %s can only have a single value: %s" msgstr "属性%sは単一の値しか持てません: %s" #: lib/active_ldap/schema.rb:566 msgid "Attribute %s: Hash must have one key-value pair only: %s" msgstr "属性 %s: ハッシュはひとつのキー・値のペアしか持ってはいけません: %s" #: lib/active_ldap/connection.rb:98 msgid ":ldap_scope connection option is deprecated. Use :scope instead." msgstr "" ":ldap_scope接続オプションは廃止予定です。代わりに:scopeを使ってください。" #: lib/active_ldap/connection.rb:156 msgid "" "ActiveLdap::Connection.establish_connection has been deprecated since 1.1.0. " "Please use ActiveLdap::Connection.setup_connection instead." msgstr "" "1.1.0からActiveLdap::Connection.establish_connectionは非推奨になりました。代" "わりにActiveLdap::Connection.setup_connectionを使ってください。" #: lib/active_ldap/connection.rb:236 msgid "since 1.1.0. " msgstr "1.1.0から。" #: lib/active_ldap/user_password.rb:10 msgid "Invalid hashed password: %s" msgstr "不正なハッシュ化されたパスワードです: %s" #: lib/active_ldap/user_password.rb:16 msgid "Unknown Hash type: %s" msgstr "未知のハッシュの種類です: %s" #: lib/active_ldap/user_password.rb:23 msgid "Can't extract salt from hashed password: %s" msgstr "ハッシュ化されたパスワードからsaltを取り出すことができません: %s" #: lib/active_ldap/user_password.rb:51 lib/active_ldap/user_password.rb:68 msgid "salt size must be == 4: %s" msgstr "saltは4文字でなければいけません: %s" #: lib/active_ldap/schema/syntaxes.rb:63 msgid "%s doesn't have the first \"'\"" msgstr "%sには最初の\"'\"がありません" #: lib/active_ldap/schema/syntaxes.rb:67 msgid "%s doesn't have the last \"'B\"" msgstr "%sには最後の\"'B\"がありません" #: lib/active_ldap/schema/syntaxes.rb:71 msgid "%s has invalid character '%s'" msgstr "%sは不正な文字'%s'を含んでいます" #: lib/active_ldap/schema/syntaxes.rb:108 msgid "%s should be TRUE or FALSE" msgstr "%sはTRUEまたはFALSEのどちらかでなければいけません" #: lib/active_ldap/schema/syntaxes.rb:121 msgid "%s should be just 2 printable characters" msgstr "%sはちょうど2文字の印字可能な文字列でなければいけません" #: lib/active_ldap/schema/syntaxes.rb:162 #: lib/active_ldap/schema/syntaxes.rb:381 msgid "%s has invalid UTF-8 character" msgstr "%sは不正なUTF-8文字を含んでいます" #: lib/active_ldap/schema/syntaxes.rb:237 msgid "%s has missing components: %s" msgstr "%sには要素が欠けています: %s" #: lib/active_ldap/schema/syntaxes.rb:240 msgid "%s is invalid time format" msgstr "%sは不正な時刻の書式です" #: lib/active_ldap/schema/syntaxes.rb:270 msgid "%s is invalid integer format" msgstr "%sは不正な整数の書式です" #: lib/active_ldap/schema/syntaxes.rb:282 msgid "invalid JPEG format" msgstr "不正なJPEG形式です" #: lib/active_ldap/schema/syntaxes.rb:323 msgid "%s is invalid numeric format" msgstr "%sは不正な数字の書式です" #: lib/active_ldap/schema/syntaxes.rb:338 msgid "%s is invalid OID format: %s" msgstr "%sは不正なOIDの書式です: %s" #: lib/active_ldap/schema/syntaxes.rb:340 msgid "%s is invalid OID format" msgstr "%sは不正なOIDの書式です" #: lib/active_ldap/schema/syntaxes.rb:353 msgid "%s has no mailbox type" msgstr "%sにメールボックスの種類がありません" #: lib/active_ldap/schema/syntaxes.rb:357 msgid "%s has unprintable character in mailbox type: '%s'" msgstr "%sはメールボックスの種類に印字不可能な文字を含んでいます: '%s'" #: lib/active_ldap/schema/syntaxes.rb:362 msgid "%s has no mailbox" msgstr "%sにメールボックスがありませんん" #: lib/active_ldap/schema/syntaxes.rb:375 #: lib/active_ldap/schema/syntaxes.rb:394 msgid "empty string" msgstr "空の文字列です" #: lib/active_ldap/schema/syntaxes.rb:398 msgid "%s has unprintable character: '%s'" msgstr "%sは印字不可能な文字を含んでいます: '%s'" #: lib/active_ldap/get_text/parser.rb:96 msgid "Ignored '%{file}'. Solve dependencies first." msgstr "'%{file}'を無視します。まず依存関係を解決してください。" #: lib/active_ldap/configuration.rb:70 msgid "%s connection is not configured" msgstr "%sの接続は設定されていません" #: lib/active_ldap/configuration.rb:110 msgid ":ldap_scope configuration option is deprecated. Use :scope instead." msgstr "" ":ldap_scope設定オプションは廃止予定です。代わりに:scopeを使ってください。" #: lib/active_ldap/configuration.rb:131 msgid "invalid URI: %s" msgstr "不正なURIです: %s" #: lib/active_ldap/configuration.rb:134 msgid "not a LDAP URI: %s" msgstr "LDAP用のURIではありません: %s" #: rails/init.rb:7 msgid "You need ActiveLdap %s or later" msgstr "ActiveLdap %s以上が必要です" #: rails/init.rb:19 msgid "You should run 'script/generator scaffold_active_ldap' to make %s." msgstr "" "%sを作るために'script/generator scaffold_active_ldap'を実行してください。" #: benchmark/bench-al.rb:14 msgid "Specify prefix for benchmarking" msgstr "ベンチマーク用のプリフィックスを指定してください" #: benchmark/bench-al.rb:15 msgid "(default: %s)" msgstr "(デフォルト: %s)" #: benchmark/bench-al.rb:186 msgid "Populating..." msgstr "データ投入中..." #: benchmark/bench-al.rb:243 msgid "Entries processed by Ruby/ActiveLdap + LDAP: %d" msgstr "Ruby/ActiveLdap + LDAPで処理したエントリ数: %d" #: benchmark/bench-al.rb:244 msgid "Entries processed by Ruby/ActiveLdap + Net::LDAP: %d" msgstr "Ruby/ActiveLdap + Net::LDAPで処理したエントリ数: %d" #: benchmark/bench-al.rb:246 msgid "" "Entries processed by Ruby/ActiveLdap + LDAP: (without object creation): %d" msgstr "Ruby/ActiveLdap + LDAPで処理したエントリ数(オブジェクト生成無し): %d" #: benchmark/bench-al.rb:249 msgid "" "Entries processed by Ruby/ActiveLdap + Net::LDAP: (without object creation): " "%d" msgstr "" "Ruby/ActiveLdap + Net::LDAPで処理したエントリ数(オブジェクト生成無し): %d" #: benchmark/bench-al.rb:252 msgid "Entries processed by Ruby/LDAP: %d" msgstr "Ruby/LDAPで処理したエントリ数: %d" #: benchmark/bench-al.rb:253 msgid "Entries processed by Net::LDAP: %d" msgstr "Net::LDAPで処理したエントリ数: %d" #: benchmark/bench-al.rb:257 msgid "Cleaning..." msgstr "削除中..." activeldap-5.2.4/po/en/0000755000004100000410000000000013464071751014716 5ustar www-datawww-dataactiveldap-5.2.4/po/en/active-ldap.po0000644000004100000410000022007513464071751017455 0ustar www-datawww-data# English translations for ActiveLdap package. # Copyright (C) 2007-2009 Kouhei Sutou # This file is distributed under the same license as the ActiveLdap package. # Kouhei Sutou , 2007. # msgid "" msgstr "" "Project-Id-Version: Ruby/ActiveLdap 1.1.1\n" "POT-Creation-Date: 2009-08-04 23:26+0900\n" "PO-Revision-Date: 2016-05-13 21:52+0900\n" "Last-Translator: Kouhei Sutou \n" "Language-Team: English\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: -:- msgid "LDAP|Attribute|aRecord" msgstr "" #: -:- msgid "LDAP|Attribute|aliasedEntryName" msgstr "" #: -:- msgid "LDAP|Attribute|aliasedObjectName" msgstr "" #: -:- msgid "LDAP|Attribute|altServer" msgstr "" #: -:- msgid "LDAP|Attribute|associatedDomain" msgstr "" #: -:- msgid "LDAP|Attribute|associatedName" msgstr "" #: -:- msgid "LDAP|Attribute|attributeTypes" msgstr "" #: -:- msgid "LDAP|Attribute|audio" msgstr "" #: -:- msgid "LDAP|Attribute|authorityRevocationList" msgstr "" #: -:- msgid "LDAP|Attribute|bootFile" msgstr "" #: -:- msgid "LDAP|Attribute|bootParameter" msgstr "" #: -:- msgid "LDAP|Attribute|buildingName" msgstr "" #: -:- msgid "LDAP|Attribute|businessCategory" msgstr "" #: -:- msgid "LDAP|Attribute|c" msgstr "" #: -:- msgid "LDAP|Attribute|cACertificate" msgstr "" #: -:- msgid "LDAP|Attribute|cNAMERecord" msgstr "" #: -:- msgid "LDAP|Attribute|carLicense" msgstr "" #: -:- msgid "LDAP|Attribute|certificateRevocationList" msgstr "" #: -:- msgid "LDAP|Attribute|cn" msgstr "" #: -:- msgid "LDAP|Attribute|co" msgstr "" #: -:- msgid "LDAP|Attribute|commonName" msgstr "" #: -:- msgid "LDAP|Attribute|countryName" msgstr "" #: -:- msgid "LDAP|Attribute|createTimestamp" msgstr "" #: -:- msgid "LDAP|Attribute|creatorsName" msgstr "" #: -:- msgid "LDAP|Attribute|crossCertificatePair" msgstr "" #: -:- msgid "LDAP|Attribute|dITRedirect" msgstr "" #: -:- msgid "LDAP|Attribute|dSAQuality" msgstr "" #: -:- msgid "LDAP|Attribute|dc" msgstr "" #: -:- msgid "LDAP|Attribute|deltaRevocationList" msgstr "" #: -:- msgid "LDAP|Attribute|departmentNumber" msgstr "" #: -:- msgid "LDAP|Attribute|description" msgstr "" #: -:- msgid "LDAP|Attribute|destinationIndicator" msgstr "" #: -:- msgid "LDAP|Attribute|displayName" msgstr "" #: -:- msgid "LDAP|Attribute|distinguishedName" msgstr "" #: -:- msgid "LDAP|Attribute|dmdName" msgstr "" #: -:- msgid "LDAP|Attribute|dnQualifier" msgstr "" #: -:- msgid "LDAP|Attribute|documentAuthor" msgstr "" #: -:- msgid "LDAP|Attribute|documentIdentifier" msgstr "" #: -:- msgid "LDAP|Attribute|documentLocation" msgstr "" #: -:- msgid "LDAP|Attribute|documentPublisher" msgstr "" #: -:- msgid "LDAP|Attribute|documentTitle" msgstr "" #: -:- msgid "LDAP|Attribute|documentVersion" msgstr "" #: -:- msgid "LDAP|Attribute|domainComponent" msgstr "" #: -:- msgid "LDAP|Attribute|drink" msgstr "" #: -:- msgid "LDAP|Attribute|dynamicSubtrees" msgstr "" #: -:- msgid "LDAP|Attribute|email" msgstr "" #: -:- msgid "LDAP|Attribute|emailAddress" msgstr "" #: -:- msgid "LDAP|Attribute|employeeNumber" msgstr "" #: -:- msgid "LDAP|Attribute|employeeType" msgstr "" #: -:- msgid "LDAP|Attribute|enhancedSearchGuide" msgstr "" #: -:- msgid "LDAP|Attribute|entryDN" msgstr "" #: -:- msgid "LDAP|Attribute|entryTtl" msgstr "" #: -:- msgid "LDAP|Attribute|entryUUID" msgstr "" #: -:- msgid "LDAP|Attribute|facsimileTelephoneNumber" msgstr "" #: -:- msgid "LDAP|Attribute|favouriteDrink" msgstr "" #: -:- msgid "LDAP|Attribute|fax" msgstr "" #: -:- msgid "LDAP|Attribute|friendlyCountryName" msgstr "" #: -:- msgid "LDAP|Attribute|gecos" msgstr "" #: -:- msgid "LDAP|Attribute|generationQualifier" msgstr "" #: -:- msgid "LDAP|Attribute|gidNumber" msgstr "" #: -:- msgid "LDAP|Attribute|givenName" msgstr "" #: -:- msgid "LDAP|Attribute|gn" msgstr "" #: -:- msgid "LDAP|Attribute|hasSubordinates" msgstr "" #: -:- msgid "LDAP|Attribute|homeDirectory" msgstr "" #: -:- msgid "LDAP|Attribute|homePhone" msgstr "" #: -:- msgid "LDAP|Attribute|homePostalAddress" msgstr "" #: -:- msgid "LDAP|Attribute|homeTelephoneNumber" msgstr "" #: -:- msgid "LDAP|Attribute|host" msgstr "" #: -:- msgid "LDAP|Attribute|houseIdentifier" msgstr "" #: -:- msgid "LDAP|Attribute|info" msgstr "" #: -:- msgid "LDAP|Attribute|initials" msgstr "" #: -:- msgid "LDAP|Attribute|internationaliSDNNumber" msgstr "" #: -:- msgid "LDAP|Attribute|ipHostNumber" msgstr "" #: -:- msgid "LDAP|Attribute|ipNetmaskNumber" msgstr "" #: -:- msgid "LDAP|Attribute|ipNetworkNumber" msgstr "" #: -:- msgid "LDAP|Attribute|ipProtocolNumber" msgstr "" #: -:- msgid "LDAP|Attribute|ipServicePort" msgstr "" #: -:- msgid "LDAP|Attribute|ipServiceProtocol" msgstr "" #: -:- msgid "LDAP|Attribute|janetMailbox" msgstr "" #: -:- msgid "LDAP|Attribute|jpegPhoto" msgstr "" #: -:- msgid "LDAP|Attribute|knowledgeInformation" msgstr "" #: -:- msgid "LDAP|Attribute|l" msgstr "" #: -:- msgid "LDAP|Attribute|labeledURI" msgstr "" #: -:- msgid "LDAP|Attribute|ldapSyntaxes" msgstr "" #: -:- msgid "LDAP|Attribute|localityName" msgstr "" #: -:- msgid "LDAP|Attribute|loginShell" msgstr "" #: -:- msgid "LDAP|Attribute|mDRecord" msgstr "" #: -:- msgid "LDAP|Attribute|mXRecord" msgstr "" #: -:- msgid "LDAP|Attribute|macAddress" msgstr "" #: -:- msgid "LDAP|Attribute|mail" msgstr "" #: -:- msgid "LDAP|Attribute|mailPreferenceOption" msgstr "" #: -:- msgid "LDAP|Attribute|manager" msgstr "" #: -:- msgid "LDAP|Attribute|matchingRuleUse" msgstr "" #: -:- msgid "LDAP|Attribute|matchingRules" msgstr "" #: -:- msgid "LDAP|Attribute|member" msgstr "" #: -:- msgid "LDAP|Attribute|memberNisNetgroup" msgstr "" #: -:- msgid "LDAP|Attribute|memberUid" msgstr "" #: -:- msgid "LDAP|Attribute|mobile" msgstr "" #: -:- msgid "LDAP|Attribute|mobileTelephoneNumber" msgstr "" #: -:- msgid "LDAP|Attribute|modifiersName" msgstr "" #: -:- msgid "LDAP|Attribute|modifyTimestamp" msgstr "" #: -:- msgid "LDAP|Attribute|nSRecord" msgstr "" #: -:- msgid "LDAP|Attribute|name" msgstr "" #: -:- msgid "LDAP|Attribute|namingContexts" msgstr "" #: -:- msgid "LDAP|Attribute|nisMapEntry" msgstr "" #: -:- msgid "LDAP|Attribute|nisMapName" msgstr "" #: -:- msgid "LDAP|Attribute|nisNetgroupTriple" msgstr "" #: -:- msgid "LDAP|Attribute|o" msgstr "" #: -:- msgid "LDAP|Attribute|objectClass" msgstr "" #: -:- msgid "LDAP|Attribute|objectClasses" msgstr "" #: -:- msgid "LDAP|Attribute|olcAccess" msgstr "" #: -:- msgid "LDAP|Attribute|olcAddContentAcl" msgstr "" #: -:- msgid "LDAP|Attribute|olcAllows" msgstr "" #: -:- msgid "LDAP|Attribute|olcArgsFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcAttributeOptions" msgstr "" #: -:- msgid "LDAP|Attribute|olcAttributeTypes" msgstr "" #: -:- msgid "LDAP|Attribute|olcAuthIDRewrite" msgstr "" #: -:- msgid "LDAP|Attribute|olcAuthzPolicy" msgstr "" #: -:- msgid "LDAP|Attribute|olcAuthzRegexp" msgstr "" #: -:- msgid "LDAP|Attribute|olcBackend" msgstr "" #: -:- msgid "LDAP|Attribute|olcConcurrency" msgstr "" #: -:- msgid "LDAP|Attribute|olcConfigDir" msgstr "" #: -:- msgid "LDAP|Attribute|olcConfigFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcConnMaxPending" msgstr "" #: -:- msgid "LDAP|Attribute|olcConnMaxPendingAuth" msgstr "" #: -:- msgid "LDAP|Attribute|olcDatabase" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbCacheFree" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbCacheSize" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbCheckpoint" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbChecksum" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbConfig" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbCryptFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbCryptKey" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbDNcacheSize" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbDirectory" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbDirtyRead" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbIDLcacheSize" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbIndex" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbLinearIndex" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbLockDetect" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbMode" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbNoSync" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbPageSize" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbSearchStack" msgstr "" #: -:- msgid "LDAP|Attribute|olcDbShmKey" msgstr "" #: -:- msgid "LDAP|Attribute|olcDefaultSearchBase" msgstr "" #: -:- msgid "LDAP|Attribute|olcDisallows" msgstr "" #: -:- msgid "LDAP|Attribute|olcDitContentRules" msgstr "" #: -:- msgid "LDAP|Attribute|olcGentleHUP" msgstr "" #: -:- msgid "LDAP|Attribute|olcHidden" msgstr "" #: -:- msgid "LDAP|Attribute|olcIdleTimeout" msgstr "" #: -:- msgid "LDAP|Attribute|olcInclude" msgstr "" #: -:- msgid "LDAP|Attribute|olcIndexIntLen" msgstr "" #: -:- msgid "LDAP|Attribute|olcIndexSubstrAnyLen" msgstr "" #: -:- msgid "LDAP|Attribute|olcIndexSubstrAnyStep" msgstr "" #: -:- msgid "LDAP|Attribute|olcIndexSubstrIfMaxLen" msgstr "" #: -:- msgid "LDAP|Attribute|olcIndexSubstrIfMinLen" msgstr "" #: -:- msgid "LDAP|Attribute|olcLastMod" msgstr "" #: -:- msgid "LDAP|Attribute|olcLdapSyntaxes" msgstr "" #: -:- msgid "LDAP|Attribute|olcLimits" msgstr "" #: -:- msgid "LDAP|Attribute|olcLocalSSF" msgstr "" #: -:- msgid "LDAP|Attribute|olcLogFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcLogLevel" msgstr "" #: -:- msgid "LDAP|Attribute|olcMaxDerefDepth" msgstr "" #: -:- msgid "LDAP|Attribute|olcMirrorMode" msgstr "" #: -:- msgid "LDAP|Attribute|olcModuleLoad" msgstr "" #: -:- msgid "LDAP|Attribute|olcModulePath" msgstr "" #: -:- msgid "LDAP|Attribute|olcMonitoring" msgstr "" #: -:- msgid "LDAP|Attribute|olcObjectClasses" msgstr "" #: -:- msgid "LDAP|Attribute|olcObjectIdentifier" msgstr "" #: -:- msgid "LDAP|Attribute|olcOverlay" msgstr "" #: -:- msgid "LDAP|Attribute|olcPasswordCryptSaltFormat" msgstr "" #: -:- msgid "LDAP|Attribute|olcPasswordHash" msgstr "" #: -:- msgid "LDAP|Attribute|olcPidFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcPlugin" msgstr "" #: -:- msgid "LDAP|Attribute|olcPluginLogFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcReadOnly" msgstr "" #: -:- msgid "LDAP|Attribute|olcReferral" msgstr "" #: -:- msgid "LDAP|Attribute|olcReplica" msgstr "" #: -:- msgid "LDAP|Attribute|olcReplicaArgsFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcReplicaPidFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcReplicationInterval" msgstr "" #: -:- msgid "LDAP|Attribute|olcReplogFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcRequires" msgstr "" #: -:- msgid "LDAP|Attribute|olcRestrict" msgstr "" #: -:- msgid "LDAP|Attribute|olcReverseLookup" msgstr "" #: -:- msgid "LDAP|Attribute|olcRootDN" msgstr "" #: -:- msgid "LDAP|Attribute|olcRootDSE" msgstr "" #: -:- msgid "LDAP|Attribute|olcRootPW" msgstr "" #: -:- msgid "LDAP|Attribute|olcSaslAuxprops" msgstr "" #: -:- msgid "LDAP|Attribute|olcSaslHost" msgstr "" #: -:- msgid "LDAP|Attribute|olcSaslRealm" msgstr "" #: -:- msgid "LDAP|Attribute|olcSaslSecProps" msgstr "" #: -:- msgid "LDAP|Attribute|olcSchemaDN" msgstr "" #: -:- msgid "LDAP|Attribute|olcSecurity" msgstr "" #: -:- msgid "LDAP|Attribute|olcServerID" msgstr "" #: -:- msgid "LDAP|Attribute|olcSizeLimit" msgstr "" #: -:- msgid "LDAP|Attribute|olcSockbufMaxIncoming" msgstr "" #: -:- msgid "LDAP|Attribute|olcSockbufMaxIncomingAuth" msgstr "" #: -:- msgid "LDAP|Attribute|olcSortVals" msgstr "" #: -:- msgid "LDAP|Attribute|olcSubordinate" msgstr "" #: -:- msgid "LDAP|Attribute|olcSuffix" msgstr "" #: -:- msgid "LDAP|Attribute|olcSyncrepl" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSCACertificateFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSCACertificatePath" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSCRLCheck" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSCRLFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSCertificateFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSCertificateKeyFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSCipherSuite" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSDHParamFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSProtocolMin" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSRandFile" msgstr "" #: -:- msgid "LDAP|Attribute|olcTLSVerifyClient" msgstr "" #: -:- msgid "LDAP|Attribute|olcThreads" msgstr "" #: -:- msgid "LDAP|Attribute|olcTimeLimit" msgstr "" #: -:- msgid "LDAP|Attribute|olcToolThreads" msgstr "" #: -:- msgid "LDAP|Attribute|olcUpdateDN" msgstr "" #: -:- msgid "LDAP|Attribute|olcUpdateRef" msgstr "" #: -:- msgid "LDAP|Attribute|olcWriteTimeout" msgstr "" #: -:- msgid "LDAP|Attribute|oncRpcNumber" msgstr "" #: -:- msgid "LDAP|Attribute|organizationName" msgstr "" #: -:- msgid "LDAP|Attribute|organizationalStatus" msgstr "" #: -:- msgid "LDAP|Attribute|organizationalUnitName" msgstr "" #: -:- msgid "LDAP|Attribute|otherMailbox" msgstr "" #: -:- msgid "LDAP|Attribute|ou" msgstr "" #: -:- msgid "LDAP|Attribute|owner" msgstr "" #: -:- msgid "LDAP|Attribute|pager" msgstr "" #: -:- msgid "LDAP|Attribute|pagerTelephoneNumber" msgstr "" #: -:- msgid "LDAP|Attribute|personalSignature" msgstr "" #: -:- msgid "LDAP|Attribute|personalTitle" msgstr "" #: -:- msgid "LDAP|Attribute|photo" msgstr "" #: -:- msgid "LDAP|Attribute|physicalDeliveryOfficeName" msgstr "" #: -:- msgid "LDAP|Attribute|pkcs9email" msgstr "" #: -:- msgid "LDAP|Attribute|postOfficeBox" msgstr "" #: -:- msgid "LDAP|Attribute|postalAddress" msgstr "" #: -:- msgid "LDAP|Attribute|postalCode" msgstr "" #: -:- msgid "LDAP|Attribute|preferredDeliveryMethod" msgstr "" #: -:- msgid "LDAP|Attribute|preferredLanguage" msgstr "" #: -:- msgid "LDAP|Attribute|presentationAddress" msgstr "" #: -:- msgid "LDAP|Attribute|protocolInformation" msgstr "" #: -:- msgid "LDAP|Attribute|pseudonym" msgstr "" #: -:- msgid "LDAP|Attribute|ref" msgstr "" #: -:- msgid "LDAP|Attribute|registeredAddress" msgstr "" #: -:- msgid "LDAP|Attribute|rfc822Mailbox" msgstr "" #: -:- msgid "LDAP|Attribute|roleOccupant" msgstr "" #: -:- msgid "LDAP|Attribute|roomNumber" msgstr "" #: -:- msgid "LDAP|Attribute|sOARecord" msgstr "" #: -:- msgid "LDAP|Attribute|sambaAcctFlags" msgstr "" #: -:- msgid "LDAP|Attribute|sambaAlgorithmicRidBase" msgstr "" #: -:- msgid "LDAP|Attribute|sambaBadPasswordCount" msgstr "" #: -:- msgid "LDAP|Attribute|sambaBadPasswordTime" msgstr "" #: -:- msgid "LDAP|Attribute|sambaBoolOption" msgstr "" #: -:- msgid "LDAP|Attribute|sambaDomainName" msgstr "" #: -:- msgid "LDAP|Attribute|sambaForceLogoff" msgstr "" #: -:- msgid "LDAP|Attribute|sambaGroupType" msgstr "" #: -:- msgid "LDAP|Attribute|sambaHomeDrive" msgstr "" #: -:- msgid "LDAP|Attribute|sambaHomePath" msgstr "" #: -:- msgid "LDAP|Attribute|sambaIntegerOption" msgstr "" #: -:- msgid "LDAP|Attribute|sambaKickoffTime" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLMPassword" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLockoutDuration" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLockoutObservationWindow" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLockoutThreshold" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLogoffTime" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLogonHours" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLogonScript" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLogonTime" msgstr "" #: -:- msgid "LDAP|Attribute|sambaLogonToChgPwd" msgstr "" #: -:- msgid "LDAP|Attribute|sambaMaxPwdAge" msgstr "" #: -:- msgid "LDAP|Attribute|sambaMinPwdAge" msgstr "" #: -:- msgid "LDAP|Attribute|sambaMinPwdLength" msgstr "" #: -:- msgid "LDAP|Attribute|sambaMungedDial" msgstr "" #: -:- msgid "LDAP|Attribute|sambaNTPassword" msgstr "" #: -:- msgid "LDAP|Attribute|sambaNextGroupRid" msgstr "" #: -:- msgid "LDAP|Attribute|sambaNextRid" msgstr "" #: -:- msgid "LDAP|Attribute|sambaNextUserRid" msgstr "" #: -:- msgid "LDAP|Attribute|sambaOptionName" msgstr "" #: -:- msgid "LDAP|Attribute|sambaPasswordHistory" msgstr "" #: -:- msgid "LDAP|Attribute|sambaPrimaryGroupSID" msgstr "" #: -:- msgid "LDAP|Attribute|sambaProfilePath" msgstr "" #: -:- msgid "LDAP|Attribute|sambaPwdCanChange" msgstr "" #: -:- msgid "LDAP|Attribute|sambaPwdHistoryLength" msgstr "" #: -:- msgid "LDAP|Attribute|sambaPwdLastSet" msgstr "" #: -:- msgid "LDAP|Attribute|sambaPwdMustChange" msgstr "" #: -:- msgid "LDAP|Attribute|sambaRefuseMachinePwdChange" msgstr "" #: -:- msgid "LDAP|Attribute|sambaSID" msgstr "" #: -:- msgid "LDAP|Attribute|sambaSIDList" msgstr "" #: -:- msgid "LDAP|Attribute|sambaShareName" msgstr "" #: -:- msgid "LDAP|Attribute|sambaStringListOption" msgstr "" #: -:- msgid "LDAP|Attribute|sambaStringOption" msgstr "" #: -:- msgid "LDAP|Attribute|sambaTrustFlags" msgstr "" #: -:- msgid "LDAP|Attribute|sambaUserWorkstations" msgstr "" #: -:- msgid "LDAP|Attribute|searchGuide" msgstr "" #: -:- msgid "LDAP|Attribute|secretary" msgstr "" #: -:- msgid "LDAP|Attribute|seeAlso" msgstr "" #: -:- msgid "LDAP|Attribute|serialNumber" msgstr "" #: -:- msgid "LDAP|Attribute|shadowExpire" msgstr "" #: -:- msgid "LDAP|Attribute|shadowFlag" msgstr "" #: -:- msgid "LDAP|Attribute|shadowInactive" msgstr "" #: -:- msgid "LDAP|Attribute|shadowLastChange" msgstr "" #: -:- msgid "LDAP|Attribute|shadowMax" msgstr "" #: -:- msgid "LDAP|Attribute|shadowMin" msgstr "" #: -:- msgid "LDAP|Attribute|shadowWarning" msgstr "" #: -:- msgid "LDAP|Attribute|singleLevelQuality" msgstr "" #: -:- msgid "LDAP|Attribute|sn" msgstr "" #: -:- msgid "LDAP|Attribute|st" msgstr "" #: -:- msgid "LDAP|Attribute|stateOrProvinceName" msgstr "" #: -:- msgid "LDAP|Attribute|street" msgstr "" #: -:- msgid "LDAP|Attribute|streetAddress" msgstr "" #: -:- msgid "LDAP|Attribute|structuralObjectClass" msgstr "" #: -:- msgid "LDAP|Attribute|subschemaSubentry" msgstr "" #: -:- msgid "LDAP|Attribute|subtreeMaximumQuality" msgstr "" #: -:- msgid "LDAP|Attribute|subtreeMinimumQuality" msgstr "" #: -:- msgid "LDAP|Attribute|supportedAlgorithms" msgstr "" #: -:- msgid "LDAP|Attribute|supportedApplicationContext" msgstr "" #: -:- msgid "LDAP|Attribute|supportedControl" msgstr "" #: -:- msgid "LDAP|Attribute|supportedExtension" msgstr "" #: -:- msgid "LDAP|Attribute|supportedFeatures" msgstr "" #: -:- msgid "LDAP|Attribute|supportedLDAPVersion" msgstr "" #: -:- msgid "LDAP|Attribute|supportedSASLMechanisms" msgstr "" #: -:- msgid "LDAP|Attribute|surname" msgstr "" #: -:- msgid "LDAP|Attribute|telephoneNumber" msgstr "" #: -:- msgid "LDAP|Attribute|teletexTerminalIdentifier" msgstr "" #: -:- msgid "LDAP|Attribute|telexNumber" msgstr "" #: -:- msgid "LDAP|Attribute|textEncodedORAddress" msgstr "" #: -:- msgid "LDAP|Attribute|title" msgstr "" #: -:- msgid "LDAP|Attribute|uid" msgstr "" #: -:- msgid "LDAP|Attribute|uidNumber" msgstr "" #: -:- msgid "LDAP|Attribute|uniqueIdentifier" msgstr "" #: -:- msgid "LDAP|Attribute|uniqueMember" msgstr "" #: -:- msgid "LDAP|Attribute|userCertificate" msgstr "" #: -:- msgid "LDAP|Attribute|userClass" msgstr "" #: -:- msgid "LDAP|Attribute|userPKCS12" msgstr "" #: -:- msgid "LDAP|Attribute|userPassword" msgstr "" #: -:- msgid "LDAP|Attribute|userSMIMECertificate" msgstr "" #: -:- msgid "LDAP|Attribute|userid" msgstr "" #: -:- msgid "LDAP|Attribute|vendorName" msgstr "" #: -:- msgid "LDAP|Attribute|vendorVersion" msgstr "" #: -:- msgid "LDAP|Attribute|x121Address" msgstr "" #: -:- msgid "LDAP|Attribute|x500UniqueIdentifier" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|aliasedObjectName|RFC4512: name of aliased object" msgstr "" #: -:- msgid "LDAP|Description|Attribute|altServer|RFC4512: alternative servers" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|associatedDomain|RFC1274: domain associated with " "object" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|associatedName|RFC1274: DN of entry associated " "with domain" msgstr "" #: -:- msgid "LDAP|Description|Attribute|attributeTypes|RFC4512: attribute types" msgstr "" #: -:- msgid "LDAP|Description|Attribute|audio|RFC1274: audio (u-law)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|authorityRevocationList|RFC2256: X.509 authority " "revocation list, use ;binary" msgstr "" #: -:- msgid "LDAP|Description|Attribute|bootFile|Boot image name" msgstr "" #: -:- msgid "LDAP|Description|Attribute|bootParameter|rpc.bootparamd parameter" msgstr "" #: -:- msgid "LDAP|Description|Attribute|buildingName|RFC1274: name of building" msgstr "" #: -:- msgid "LDAP|Description|Attribute|businessCategory|RFC2256: business category" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|cACertificate|RFC2256: X.509 CA certificate, use ;" "binary" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|carLicense|RFC2798: vehicle license or " "registration plate" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|certificateRevocationList|RFC2256: X.509 " "certificate revocation list, use ;binary" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|cn|RFC4519: common name(s) for which the entity " "is known by" msgstr "" #: -:- msgid "LDAP|Description|Attribute|co|RFC1274: friendly country name" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|createTimestamp|RFC4512: time which object was " "created" msgstr "" #: -:- msgid "LDAP|Description|Attribute|creatorsName|RFC4512: name of creator" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|crossCertificatePair|RFC2256: X.509 cross " "certificate pair, use ;binary" msgstr "" #: -:- msgid "LDAP|Description|Attribute|c|RFC2256: ISO-3166 country 2-letter code" msgstr "" #: -:- msgid "LDAP|Description|Attribute|dITRedirect|RFC1274: DIT Redirect" msgstr "" #: -:- msgid "LDAP|Description|Attribute|dSAQuality|RFC1274: DSA Quality" msgstr "" #: -:- msgid "LDAP|Description|Attribute|dc|RFC1274/2247: domain component" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|deltaRevocationList|RFC2256: delta revocation " "list; use ;binary" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|departmentNumber|RFC2798: identifies a department " "within an organization" msgstr "" #: -:- msgid "LDAP|Description|Attribute|description|RFC4519: descriptive information" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|destinationIndicator|RFC2256: destination " "indicator" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|displayName|RFC2798: preferred name to be used " "when displaying entries" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|distinguishedName|RFC4519: common supertype of DN " "attributes" msgstr "" #: -:- msgid "LDAP|Description|Attribute|dmdName|RFC2256: name of DMD" msgstr "" #: -:- msgid "LDAP|Description|Attribute|dnQualifier|RFC2256: DN qualifier" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|documentAuthor|RFC1274: DN of author of document" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|documentIdentifier|RFC1274: unique identifier of " "document" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|documentLocation|RFC1274: location of document " "original" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|documentPublisher|RFC1274: publisher of document" msgstr "" #: -:- msgid "LDAP|Description|Attribute|documentTitle|RFC1274: title of document" msgstr "" #: -:- msgid "LDAP|Description|Attribute|documentVersion|RFC1274: version of document" msgstr "" #: -:- msgid "LDAP|Description|Attribute|drink|RFC1274: favorite drink" msgstr "" #: -:- msgid "LDAP|Description|Attribute|dynamicSubtrees|RFC2589: dynamic subtrees" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|email|RFC3280: legacy attribute for email " "addresses in DNs" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|employeeNumber|RFC2798: numerically identifies an " "employee within an organization" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|employeeType|RFC2798: type of employment for a " "person" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|enhancedSearchGuide|RFC2256: enhanced search guide" msgstr "" #: -:- msgid "LDAP|Description|Attribute|entryDN|DN of the entry" msgstr "" #: -:- msgid "LDAP|Description|Attribute|entryTtl|RFC2589: entry time-to-live" msgstr "" #: -:- msgid "LDAP|Description|Attribute|entryUUID|UUID of the entry" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|facsimileTelephoneNumber|RFC2256: Facsimile (Fax) " "Telephone Number" msgstr "" #: -:- msgid "LDAP|Description|Attribute|gecos|The GECOS field; the common name" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|generationQualifier|RFC2256: name qualifier " "indicating a generation" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|gidNumber|RFC2307: An integer uniquely " "identifying a group in an administrative domain" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|givenName|RFC2256: first name(s) for which the " "entity is known by" msgstr "" #: -:- msgid "LDAP|Description|Attribute|hasSubordinates|X.501: entry has children" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|homeDirectory|The absolute path to the home " "directory" msgstr "" #: -:- msgid "LDAP|Description|Attribute|homePhone|RFC1274: home telephone number" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|homePostalAddress|RFC1274: home postal address" msgstr "" #: -:- msgid "LDAP|Description|Attribute|host|RFC1274: host computer" msgstr "" #: -:- msgid "LDAP|Description|Attribute|houseIdentifier|RFC2256: house identifier" msgstr "" #: -:- msgid "LDAP|Description|Attribute|info|RFC1274: general information" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|initials|RFC2256: initials of some or all of " "names, but not the surname(s)." msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|internationaliSDNNumber|RFC2256: international " "ISDN number" msgstr "" #: -:- msgid "LDAP|Description|Attribute|ipHostNumber|IP address" msgstr "" #: -:- msgid "LDAP|Description|Attribute|ipNetmaskNumber|IP netmask" msgstr "" #: -:- msgid "LDAP|Description|Attribute|ipNetworkNumber|IP network" msgstr "" #: -:- msgid "LDAP|Description|Attribute|janetMailbox|RFC1274: Janet mailbox" msgstr "" #: -:- msgid "LDAP|Description|Attribute|jpegPhoto|RFC2798: a JPEG image" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|knowledgeInformation|RFC2256: knowledge " "information" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|labeledURI|RFC2079: Uniform Resource Identifier " "with optional label" msgstr "" #: -:- msgid "LDAP|Description|Attribute|ldapSyntaxes|RFC4512: LDAP syntaxes" msgstr "" #: -:- msgid "LDAP|Description|Attribute|loginShell|The path to the login shell" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|l|RFC2256: locality which this object resides in" msgstr "" #: -:- msgid "LDAP|Description|Attribute|macAddress|MAC address" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|mailPreferenceOption|RFC1274: mail preference " "option" msgstr "" #: -:- msgid "LDAP|Description|Attribute|mail|RFC1274: RFC822 Mailbox" msgstr "" #: -:- msgid "LDAP|Description|Attribute|manager|RFC1274: DN of manager" msgstr "" #: -:- msgid "LDAP|Description|Attribute|matchingRuleUse|RFC4512: matching rule uses" msgstr "" #: -:- msgid "LDAP|Description|Attribute|matchingRules|RFC4512: matching rules" msgstr "" #: -:- msgid "LDAP|Description|Attribute|member|RFC2256: member of a group" msgstr "" #: -:- msgid "LDAP|Description|Attribute|mobile|RFC1274: mobile telephone number" msgstr "" #: -:- msgid "LDAP|Description|Attribute|modifiersName|RFC4512: name of last modifier" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|modifyTimestamp|RFC4512: time which object was " "last modified" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|name|RFC4519: common supertype of name attributes" msgstr "" #: -:- msgid "LDAP|Description|Attribute|namingContexts|RFC4512: naming contexts" msgstr "" #: -:- msgid "LDAP|Description|Attribute|nisNetgroupTriple|Netgroup triple" msgstr "" #: -:- msgid "LDAP|Description|Attribute|objectClasses|RFC4512: object classes" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|objectClass|RFC4512: object classes of the entity" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcAccess|Access Control List" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcAddContentAcl|Check ACLs against content of " "Add ops" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcAllows|Allowed set of deprecated features" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcArgsFile|File for slapd command line options" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcAttributeTypes|OpenLDAP attributeTypes" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcBackend|A type of backend" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcConfigDir|Directory for slapd configuration " "backend" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcConfigFile|File for slapd configuration " "directives" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDatabase|The backend type for a database " "instance" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbCacheFree|Number of extra entries to free " "when max is reached" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcDbCacheSize|Entry cache size in entries" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbCheckpoint|Database checkpoint interval in " "kbytes and minutes" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbChecksum|Enable database checksum validation" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbConfig|BerkeleyDB DB_CONFIG configuration " "directives" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbCryptFile|Pathname of file containing the DB " "encryption key" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcDbCryptKey|DB encryption key" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcDbDNcacheSize|DN cache size" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbDirectory|Directory for database content" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbDirtyRead|Allow reads of uncommitted data" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcDbIDLcacheSize|IDL cache size in IDLs" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcDbIndex|Attribute index parameters" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbLinearIndex|Index attributes one at a time" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcDbLockDetect|Deadlock detection algorithm" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcDbMode|Unix permissions of database files" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbNoSync|Disable synchronous database writes" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbPageSize|Page size of specified DB, in Kbytes" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDbSearchStack|Depth of search stack in IDLs" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcDbShmKey|Key for shared memory region" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcDitContentRules|OpenLDAP DIT content rules" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcLdapSyntaxes|OpenLDAP ldapSyntax" msgstr "" #: -:- msgid "LDAP|Description|Attribute|olcObjectClasses|OpenLDAP object classes" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|olcSortVals|Attributes whose values will always " "be sorted" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|organizationalStatus|RFC1274: organizational " "status" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|ou|RFC2256: organizational unit this object " "belongs to" msgstr "" #: -:- msgid "LDAP|Description|Attribute|owner|RFC2256: owner (of the object)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|o|RFC2256: organization this object belongs to" msgstr "" #: -:- msgid "LDAP|Description|Attribute|pager|RFC1274: pager telephone number" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|personalSignature|RFC1274: Personal Signature (G3 " "fax)" msgstr "" #: -:- msgid "LDAP|Description|Attribute|personalTitle|RFC1274: personal title" msgstr "" #: -:- msgid "LDAP|Description|Attribute|photo|RFC1274: photo (G3 fax)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|physicalDeliveryOfficeName|RFC2256: Physical " "Delivery Office Name" msgstr "" #: -:- msgid "LDAP|Description|Attribute|postOfficeBox|RFC2256: Post Office Box" msgstr "" #: -:- msgid "LDAP|Description|Attribute|postalAddress|RFC2256: postal address" msgstr "" #: -:- msgid "LDAP|Description|Attribute|postalCode|RFC2256: postal code" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|preferredDeliveryMethod|RFC2256: preferred " "delivery method" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|preferredLanguage|RFC2798: preferred written or " "spoken language for a person" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|presentationAddress|RFC2256: presentation address" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|protocolInformation|RFC2256: protocol information" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|pseudonym|X.520(4th): pseudonym for the object" msgstr "" #: -:- msgid "LDAP|Description|Attribute|ref|RFC3296: subordinate referral URL" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|registeredAddress|RFC2256: registered postal " "address" msgstr "" #: -:- msgid "LDAP|Description|Attribute|roleOccupant|RFC2256: occupant of role" msgstr "" #: -:- msgid "LDAP|Description|Attribute|roomNumber|RFC1274: room number" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaAcctFlags|Account Flags" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaAlgorithmicRidBase|Base at which the samba " "RID generation algorithm should operate" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaBadPasswordCount|Bad password attempt count" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaBadPasswordTime|Time of the last bad " "password attempt" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaBoolOption|A boolean option" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaDomainName|Windows NT domain to which the " "user belongs" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaForceLogoff|Disconnect Users outside logon " "hours (default: -1 => off, 0 => on)" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaGroupType|NT Group Type" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaHomeDrive|Driver letter of home directory " "mapping" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaHomePath|Home directory UNC path" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaIntegerOption|An integer option" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaKickoffTime|Timestamp of when the user will " "be logged off automatically" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaLMPassword|LanManager Password" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaLockoutDuration|Lockout duration in minutes " "(default: 30, -1 => forever)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaLockoutObservationWindow|Reset time after " "lockout in minutes (default: 30)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaLockoutThreshold|Lockout users after bad " "logon attempts (default: 0 => off)" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaLogoffTime|Timestamp of last logoff" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaLogonHours|Logon Hours" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaLogonScript|Logon script path" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaLogonTime|Timestamp of last logon" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaLogonToChgPwd|Force Users to logon for " "password change (default: 0 => off, 2 => on)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaMaxPwdAge|Maximum password age, in seconds " "(default: -1 => never expire passwords)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaMinPwdAge|Minimum password age, in seconds " "(default: 0 => allow immediate password change)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaMinPwdLength|Minimal password length " "(default: 5)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaMungedDial|Base64 encoded user parameter " "string" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaNTPassword|MD4 hash of the unicode password" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaNextGroupRid|Next NT rid to give out for " "groups" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaNextRid|Next NT rid to give out for anything" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaNextUserRid|Next NT rid to give our for users" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaOptionName|Option Name" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaPasswordHistory|Concatenated MD4 hashes of " "the unicode passwords used on this account" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaPrimaryGroupSID|Primary Group Security ID" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaProfilePath|Roaming profile path" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaPwdCanChange|Timestamp of when the user is " "allowed to update the password" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaPwdHistoryLength|Length of Password History " "Entries (default: 0 => off)" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaPwdLastSet|Timestamp of the last password " "update" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaPwdMustChange|Timestamp of when the password " "will expire" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaRefuseMachinePwdChange|Allow Machine " "Password changes (default: 0 => off)" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaSIDList|Security ID List" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaSID|Security ID" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaShareName|Share Name" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaStringListOption|A string list option" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaStringOption|A string option" msgstr "" #: -:- msgid "LDAP|Description|Attribute|sambaTrustFlags|Trust Password Flags" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sambaUserWorkstations|List of user workstations " "the user is allowed to logon to" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|searchGuide|RFC2256: search guide, deprecated by " "enhancedSearchGuide" msgstr "" #: -:- msgid "LDAP|Description|Attribute|secretary|RFC1274: DN of secretary" msgstr "" #: -:- msgid "LDAP|Description|Attribute|seeAlso|RFC4519: DN of related object" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|serialNumber|RFC2256: serial number of the entity" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|singleLevelQuality|RFC1274: Single Level Quality" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|sn|RFC2256: last (family) name(s) for which the " "entity is known by" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|street|RFC2256: street address of this object" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|structuralObjectClass|RFC4512: structural object " "class of entry" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|st|RFC2256: state or province which this object " "resides in" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|subschemaSubentry|RFC4512: name of controlling " "subschema entry" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|subtreeMaximumQuality|RFC1274: Subtree Maximun " "Quality" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|subtreeMinimumQuality|RFC1274: Subtree Mininum " "Quality" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|supportedAlgorithms|RFC2256: supported algorithms" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|supportedApplicationContext|RFC2256: supported " "application context" msgstr "" #: -:- msgid "LDAP|Description|Attribute|supportedControl|RFC4512: supported controls" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|supportedExtension|RFC4512: supported extended " "operations" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|supportedFeatures|RFC4512: features supported by " "the server" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|supportedLDAPVersion|RFC4512: supported LDAP " "versions" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|supportedSASLMechanisms|RFC4512: supported SASL " "mechanisms" msgstr "" #: -:- msgid "LDAP|Description|Attribute|telephoneNumber|RFC2256: Telephone Number" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|teletexTerminalIdentifier|RFC2256: Teletex " "Terminal Identifier" msgstr "" #: -:- msgid "LDAP|Description|Attribute|telexNumber|RFC2256: Telex Number" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|title|RFC2256: title associated with the entity" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|uidNumber|RFC2307: An integer uniquely " "identifying a user in an administrative domain" msgstr "" #: -:- msgid "LDAP|Description|Attribute|uid|RFC4519: user identifier" msgstr "" #: -:- msgid "LDAP|Description|Attribute|uniqueIdentifier|RFC1274: unique identifer" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|uniqueMember|RFC2256: unique member of a group" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|userCertificate|RFC2256: X.509 user certificate, " "use ;binary" msgstr "" #: -:- msgid "LDAP|Description|Attribute|userClass|RFC1274: category of user" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|userPKCS12|RFC2798: personal identity " "information, a PKCS #12 PFX" msgstr "" #: -:- msgid "LDAP|Description|Attribute|userPassword|RFC4519/2307: password of user" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|userSMIMECertificate|RFC2798: PKCS#7 SignedData " "used to support S/MIME" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|vendorName|RFC3045: name of implementation vendor" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|vendorVersion|RFC3045: version of implementation" msgstr "" #: -:- msgid "LDAP|Description|Attribute|x121Address|RFC2256: X.121 Address" msgstr "" #: -:- msgid "" "LDAP|Description|Attribute|x500UniqueIdentifier|RFC2256: X.500 unique " "identifier" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|OpenLDAPdisplayableObject|OpenLDAP Displayable " "Object" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|OpenLDAPorg|OpenLDAP Organizational Object" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|OpenLDAPou|OpenLDAP Organizational Unit Object" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|OpenLDAPperson|OpenLDAP Person" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|OpenLDAProotDSE|OpenLDAP Root DSE object" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|alias|RFC4512: an alias" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|applicationEntity|RFC2256: an application entity" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|applicationProcess|RFC2256: an application " "process" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|bootableDevice|A device with boot parameters" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|certificationAuthority|RFC2256: a certificate " "authority" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|country|RFC2256: a country" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|dSA|RFC2256: a directory system agent (a server)" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|dcObject|RFC2247: domain component object" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|deltaCRL|RFC2587: PKI user" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|device|RFC2256: a device" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|domainRelatedObject|RFC1274: an object related " "to an domain" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|dynamicObject|RFC2589: Dynamic Object" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|extensibleObject|RFC4512: extensible object" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|groupOfNames|RFC2256: a group of names (DNs)" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|groupOfUniqueNames|RFC2256: a group of unique " "names (DN and Unique Identifier)" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|ieee802Device|A device with a MAC address" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|inetOrgPerson|RFC2798: Internet Organizational " "Person" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|ipHost|Abstraction of a host, an IP device" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|ipNetwork|Abstraction of an IP network" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|ipProtocol|Abstraction of an IP protocol" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|ipService|Abstraction an Internet Protocol " "service" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|labeledURIObject|RFC2079: object that contains " "the URI attribute type" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|locality|RFC2256: a locality" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|nisMap|A generic abstraction of a NIS map" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|nisNetgroup|Abstraction of a netgroup" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|nisObject|An entry in a NIS map" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|olcBackendConfig|OpenLDAP Backend-specific " "options" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|olcBdbConfig|BDB backend configuration" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|olcConfig|OpenLDAP configuration object" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|olcDatabaseConfig|OpenLDAP Database-specific " "options" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|olcFrontendConfig|OpenLDAP frontend " "configuration" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|olcGlobal|OpenLDAP Global configuration options" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|olcIncludeFile|OpenLDAP configuration include " "file" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|olcLdifConfig|LDIF backend configuration" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|olcModuleList|OpenLDAP dynamic module info" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|olcOverlayConfig|OpenLDAP Overlay-specific " "options" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|olcSchemaConfig|OpenLDAP schema object" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|oncRpc|Abstraction of an ONC/RPC binding" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|organizationalPerson|RFC2256: an organizational " "person" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|organizationalRole|RFC2256: an organizational " "role" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|organizationalUnit|RFC2256: an organizational " "unit" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|organization|RFC2256: an organization" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|person|RFC2256: a person" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|pkiCA|RFC2587: PKI certificate authority" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|pkiUser|RFC2587: a PKI user" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|posixAccount|Abstraction of an account with " "POSIX attributes" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|posixGroup|Abstraction of a group of accounts" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|referral|namedref: named subordinate referral" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|residentialPerson|RFC2256: an residential person" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|sambaConfigOption|Samba Configuration Option" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|sambaConfig|Samba Configuration Section" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|sambaDomain|Samba Domain Information" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|sambaGroupMapping|Samba Group Mapping" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|sambaIdmapEntry|Mapping from a SID to an ID" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|sambaSamAccount|Samba 3.0 Auxilary SAM Account" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|sambaShare|Samba Share Section" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|sambaSidEntry|Structural Class for a SID" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|sambaTrustPassword|Samba Trust Password" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|sambaUnixIdPool|Pool for allocating UNIX uids/" "gids" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|shadowAccount|Additional attributes for shadow " "passwords" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|simpleSecurityObject|RFC1274: simple security " "object" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|strongAuthenticationUser|RFC2256: a strong " "authentication user" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|subentry|RFC3672: subentry" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|subschema|RFC4512: controlling subschema (sub)" "entry" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|top|top of the superclass chain" msgstr "" #: -:- msgid "LDAP|Description|ObjectClass|uidObject|RFC2377: uid object" msgstr "" #: -:- msgid "" "LDAP|Description|ObjectClass|userSecurityInformation|RFC2256: a user " "security information" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.2.36.79672281.1.5.0|RDN" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.1.1.0.0|RFC2307 NIS Netgroup Triple" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.1.1.0.1|RFC2307 Boot Parameter" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.1.16.1|UUID" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.10|Certificate Pair" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.11|Country String" msgstr "" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.12|Distinguished Name" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.14|Delivery Method" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.15|Directory String" msgstr "" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.22|Facsimile Telephone " "Number" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.24|Generalized Time" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.26|IA5 String" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.27|Integer" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.28|JPEG" msgstr "" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.34|Name And Optional UID" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.36|Numeric String" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.38|OID" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.39|Other Mailbox" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.40|Octet String" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.41|Postal Address" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.44|Printable String" msgstr "" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.45|SubtreeSpecification" msgstr "" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.49|Supported Algorithm" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.4|Audio" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.50|Telephone Number" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.52|Telex Number" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.5|Binary" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.6|Bit String" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.7|Boolean" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.8|Certificate" msgstr "" #: -:- msgid "LDAP|Description|Syntax|1.3.6.1.4.1.1466.115.121.1.9|Certificate List" msgstr "" #: -:- msgid "" "LDAP|Description|Syntax|1.3.6.1.4.1.4203.666.11.10.2.1|X.509 " "AttributeCertificate" msgstr "" #: -:- msgid "LDAP|ObjectClass|LDAProotDSE" msgstr "" #: -:- msgid "LDAP|ObjectClass|OpenLDAPdisplayableObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|OpenLDAPorg" msgstr "" #: -:- msgid "LDAP|ObjectClass|OpenLDAPou" msgstr "" #: -:- msgid "LDAP|ObjectClass|OpenLDAPperson" msgstr "" #: -:- msgid "LDAP|ObjectClass|OpenLDAProotDSE" msgstr "" #: -:- msgid "LDAP|ObjectClass|RFC822localPart" msgstr "" #: -:- msgid "LDAP|ObjectClass|account" msgstr "" #: -:- msgid "LDAP|ObjectClass|alias" msgstr "" #: -:- msgid "LDAP|ObjectClass|applicationEntity" msgstr "" #: -:- msgid "LDAP|ObjectClass|applicationProcess" msgstr "" #: -:- msgid "LDAP|ObjectClass|bootableDevice" msgstr "" #: -:- msgid "LDAP|ObjectClass|cRLDistributionPoint" msgstr "" #: -:- msgid "LDAP|ObjectClass|certificationAuthority" msgstr "" #: -:- msgid "LDAP|ObjectClass|certificationAuthority-V2" msgstr "" #: -:- msgid "LDAP|ObjectClass|country" msgstr "" #: -:- msgid "LDAP|ObjectClass|dNSDomain" msgstr "" #: -:- msgid "LDAP|ObjectClass|dSA" msgstr "" #: -:- msgid "LDAP|ObjectClass|dcObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|deltaCRL" msgstr "" #: -:- msgid "LDAP|ObjectClass|device" msgstr "" #: -:- msgid "LDAP|ObjectClass|dmd" msgstr "" #: -:- msgid "LDAP|ObjectClass|document" msgstr "" #: -:- msgid "LDAP|ObjectClass|documentSeries" msgstr "" #: -:- msgid "LDAP|ObjectClass|domain" msgstr "" #: -:- msgid "LDAP|ObjectClass|domainRelatedObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|dynamicObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|extensibleObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|friendlyCountry" msgstr "" #: -:- msgid "LDAP|ObjectClass|groupOfNames" msgstr "" #: -:- msgid "LDAP|ObjectClass|groupOfUniqueNames" msgstr "" #: -:- msgid "LDAP|ObjectClass|ieee802Device" msgstr "" #: -:- msgid "LDAP|ObjectClass|inetOrgPerson" msgstr "" #: -:- msgid "LDAP|ObjectClass|ipHost" msgstr "" #: -:- msgid "LDAP|ObjectClass|ipNetwork" msgstr "" #: -:- msgid "LDAP|ObjectClass|ipProtocol" msgstr "" #: -:- msgid "LDAP|ObjectClass|ipService" msgstr "" #: -:- msgid "LDAP|ObjectClass|labeledURIObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|locality" msgstr "" #: -:- msgid "LDAP|ObjectClass|newPilotPerson" msgstr "" #: -:- msgid "LDAP|ObjectClass|nisMap" msgstr "" #: -:- msgid "LDAP|ObjectClass|nisNetgroup" msgstr "" #: -:- msgid "LDAP|ObjectClass|nisObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcBackendConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcBdbConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcDatabaseConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcFrontendConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcGlobal" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcIncludeFile" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcLdifConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcModuleList" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcOverlayConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|olcSchemaConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|oncRpc" msgstr "" #: -:- msgid "LDAP|ObjectClass|organization" msgstr "" #: -:- msgid "LDAP|ObjectClass|organizationalPerson" msgstr "" #: -:- msgid "LDAP|ObjectClass|organizationalRole" msgstr "" #: -:- msgid "LDAP|ObjectClass|organizationalUnit" msgstr "" #: -:- msgid "LDAP|ObjectClass|person" msgstr "" #: -:- msgid "LDAP|ObjectClass|pilotDSA" msgstr "" #: -:- msgid "LDAP|ObjectClass|pilotOrganization" msgstr "" #: -:- msgid "LDAP|ObjectClass|pilotPerson" msgstr "" #: -:- msgid "LDAP|ObjectClass|pkiCA" msgstr "" #: -:- msgid "LDAP|ObjectClass|pkiUser" msgstr "" #: -:- msgid "LDAP|ObjectClass|posixAccount" msgstr "" #: -:- msgid "LDAP|ObjectClass|posixGroup" msgstr "" #: -:- msgid "LDAP|ObjectClass|qualityLabelledData" msgstr "" #: -:- msgid "LDAP|ObjectClass|referral" msgstr "" #: -:- msgid "LDAP|ObjectClass|residentialPerson" msgstr "" #: -:- msgid "LDAP|ObjectClass|room" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaConfig" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaConfigOption" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaDomain" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaGroupMapping" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaIdmapEntry" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaSamAccount" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaShare" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaSidEntry" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaTrustPassword" msgstr "" #: -:- msgid "LDAP|ObjectClass|sambaUnixIdPool" msgstr "" #: -:- msgid "LDAP|ObjectClass|shadowAccount" msgstr "" #: -:- msgid "LDAP|ObjectClass|simpleSecurityObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|strongAuthenticationUser" msgstr "" #: -:- msgid "LDAP|ObjectClass|subentry" msgstr "" #: -:- msgid "LDAP|ObjectClass|subschema" msgstr "" #: -:- msgid "LDAP|ObjectClass|top" msgstr "" #: -:- msgid "LDAP|ObjectClass|uidObject" msgstr "" #: -:- msgid "LDAP|ObjectClass|userSecurityInformation" msgstr "" #: -:- msgid "LDAP|Syntax|1.2.36.79672281.1.5.0" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.1.1.0.0" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.1.1.0.1" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.1.16.1" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.10" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.11" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.12" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.14" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.15" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.22" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.24" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.26" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.27" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.28" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.34" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.36" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.38" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.39" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.4" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.40" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.41" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.44" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.45" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.49" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.5" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.50" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.52" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.6" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.7" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.8" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.1466.115.121.1.9" msgstr "" #: -:- msgid "LDAP|Syntax|1.3.6.1.4.1.4203.666.11.10.2.1" msgstr "" #: lib/active_ldap/object_class.rb:53 msgid "Value in objectClass array is not a String: %s" msgstr "" #: lib/active_ldap/object_class.rb:67 msgid "unknown objectClass in LDAP server: %s" msgstr "" #: lib/active_ldap/object_class.rb:85 msgid "Can't remove required objectClass: %s" msgstr "" #: lib/active_ldap/adapter/jndi.rb:105 lib/active_ldap/adapter/ldap.rb:203 #: lib/active_ldap/adapter/net_ldap.rb:155 msgid "%s is not one of the available connect methods: %s" msgstr "" #: lib/active_ldap/adapter/jndi.rb:118 lib/active_ldap/adapter/ldap.rb:216 #: lib/active_ldap/adapter/net_ldap.rb:168 msgid "%s is not one of the available LDAP scope: %s" msgstr "" #: lib/active_ldap/adapter/jndi.rb:176 lib/active_ldap/adapter/ldap.rb:280 #: lib/active_ldap/adapter/net_ldap.rb:290 msgid "unknown type: %s" msgstr "" #: lib/active_ldap/adapter/ldap.rb:108 msgid "No matches: filter: %s: attributes: %s" msgstr "" #: lib/active_ldap/adapter/ldap.rb:162 msgid "modify RDN with new superior" msgstr "" #: lib/active_ldap/adapter/net_ldap.rb:211 msgid "unsupported qops: %s" msgstr "" #: lib/active_ldap/adapter/base.rb:84 msgid "Bound to %s by SASL as %s" msgstr "" #: lib/active_ldap/adapter/base.rb:86 msgid "Bound to %s by simple as %s" msgstr "" #: lib/active_ldap/adapter/base.rb:88 msgid "Bound to %s as anonymous" msgstr "" #: lib/active_ldap/adapter/base.rb:91 msgid "All authentication methods for %s exhausted." msgstr "" #: lib/active_ldap/adapter/base.rb:171 msgid "Ignore error %s(%s): filter %s: attributes: %s" msgstr "" #: lib/active_ldap/adapter/base.rb:187 lib/active_ldap/adapter/base.rb:206 #: lib/active_ldap/adapter/base.rb:208 lib/active_ldap/adapter/base.rb:210 #: lib/active_ldap/adapter/base.rb:212 lib/active_ldap/adapter/base.rb:222 #: lib/active_ldap/adapter/base.rb:228 msgid "%s: %s" msgstr "" #: lib/active_ldap/adapter/base.rb:192 lib/active_ldap/adapter/base.rb:202 msgid "No such entry: %s" msgstr "" #: lib/active_ldap/adapter/base.rb:293 msgid "password_block not nil or Proc object. Ignoring." msgstr "" #: lib/active_ldap/adapter/base.rb:314 msgid "Requested action timed out." msgstr "" #: lib/active_ldap/adapter/base.rb:355 msgid "Skip simple bind with empty password." msgstr "" #: lib/active_ldap/adapter/base.rb:359 msgid "Can't use empty password for simple bind." msgstr "" #: lib/active_ldap/adapter/base.rb:551 msgid "invalid logical operator: %s: available operators: %s" msgstr "" #: lib/active_ldap/adapter/base.rb:566 msgid "Attempting to reconnect" msgstr "" #: lib/active_ldap/adapter/base.rb:579 msgid "" "Reconnect to server failed: %s: %s\n" "Reconnect to server failed backtrace:\n" "%s" msgstr "" #: lib/active_ldap/adapter/base.rb:589 msgid "Giving up trying to reconnect to LDAP server." msgstr "" #: lib/active_ldap/acts/tree.rb:66 msgid "parent must be an entry or parent DN: %s" msgstr "" #: lib/active_ldap/operations.rb:49 msgid ":ldap_scope search option is deprecated. Use :scope instead." msgstr "" #: lib/active_ldap/operations.rb:258 msgid "Invalid order: %s" msgstr "" #: lib/active_ldap/operations.rb:294 msgid "Couldn't find %s without a DN" msgstr "" #: lib/active_ldap/operations.rb:316 msgid "Couldn't find %s: DN: %s: filter: %s" msgstr "" #: lib/active_ldap/operations.rb:319 msgid "Couldn't find %s: DN: %s" msgstr "" #: lib/active_ldap/operations.rb:346 msgid "Couldn't find all %s: DNs (%s): filter: %s" msgstr "" #: lib/active_ldap/operations.rb:349 msgid "Couldn't find all %s: DNs (%s)" msgstr "" #: lib/active_ldap/operations.rb:504 msgid "Failed to delete LDAP entry: <%s>: %s" msgstr "" #: lib/active_ldap/associations.rb:68 msgid "" ":foreign_key belongs_to(:many) option is deprecated since 1.1.0. Use :" "primary_key instead." msgstr "" #: lib/active_ldap/associations.rb:136 msgid "" ":primary_key and :foreign_key has_many options are inverted their mean since " "1.1.0. Please invert them." msgstr "" #: lib/active_ldap/ldif.rb:396 msgid "version spec is missing" msgstr "" #: lib/active_ldap/ldif.rb:400 msgid "version number is missing" msgstr "" #: lib/active_ldap/ldif.rb:404 msgid "unsupported version: %d" msgstr "" #: lib/active_ldap/ldif.rb:408 msgid "separator is missing" msgstr "" #: lib/active_ldap/ldif.rb:412 msgid "'dn:' is missing" msgstr "" #: lib/active_ldap/ldif.rb:416 msgid "DN is missing" msgstr "" #: lib/active_ldap/ldif.rb:420 msgid "DN is invalid: %s: %s" msgstr "" #: lib/active_ldap/ldif.rb:424 msgid "DN has an invalid character: %s" msgstr "" #: lib/active_ldap/ldif.rb:428 lib/active_ldap/distinguished_name.rb:144 msgid "attribute type is missing" msgstr "" #: lib/active_ldap/ldif.rb:432 msgid "option is missing" msgstr "" #: lib/active_ldap/ldif.rb:436 msgid "':' is missing" msgstr "" #: lib/active_ldap/ldif.rb:440 msgid "URI is invalid: %s: %s" msgstr "" #: lib/active_ldap/ldif.rb:444 msgid "'-' is missing" msgstr "" #: lib/active_ldap/ldif.rb:448 msgid "unknown change type: %s" msgstr "" #: lib/active_ldap/ldif.rb:452 msgid "change type is missing" msgstr "" #: lib/active_ldap/ldif.rb:456 msgid "control type is missing" msgstr "" #: lib/active_ldap/ldif.rb:460 msgid "criticality is missing" msgstr "" #: lib/active_ldap/ldif.rb:464 msgid "change type value is missing" msgstr "" #: lib/active_ldap/ldif.rb:468 msgid "attribute spec is missing" msgstr "" #: lib/active_ldap/ldif.rb:472 msgid "'newrdn:' is missing" msgstr "" #: lib/active_ldap/ldif.rb:476 msgid "new RDN value is missing" msgstr "" #: lib/active_ldap/ldif.rb:480 msgid "'deleteoldrdn:' is missing" msgstr "" #: lib/active_ldap/ldif.rb:484 msgid "delete old RDN value is missing" msgstr "" #: lib/active_ldap/ldif.rb:488 msgid "new superior value is missing" msgstr "" #: lib/active_ldap/ldif.rb:492 msgid "unknown modify type: %s" msgstr "" #: lib/active_ldap/ldif.rb:765 msgid "invalid criticality value: %s" msgstr "" #: lib/active_ldap/ldif.rb:808 msgid "invalid deleteoldrdn value: %s" msgstr "" #: lib/active_ldap/distinguished_name.rb:136 msgid "name component is missing" msgstr "" #: lib/active_ldap/distinguished_name.rb:140 msgid "relative distinguished name (RDN) is missing" msgstr "" #: lib/active_ldap/distinguished_name.rb:148 msgid "attribute value is missing" msgstr "" #: lib/active_ldap/distinguished_name.rb:152 msgid "found unmatched quotation" msgstr "" #: lib/active_ldap/distinguished_name.rb:188 msgid "%s isn't sub DN of %s" msgstr "" #: lib/active_ldap/validations.rb:97 msgid "is duplicated: %s" msgstr "" #: lib/active_ldap/validations.rb:108 msgid "is invalid: %s" msgstr "" #: lib/active_ldap/validations.rb:112 msgid "isn't set: %s" msgstr "" #: lib/active_ldap/validations.rb:134 msgid "has excluded value: %s" msgid_plural "has excluded values: %s" msgstr[0] "" msgstr[1] "" #: lib/active_ldap/validations.rb:169 msgid "is required attribute by objectClass '%s'" msgstr "" #: lib/active_ldap/validations.rb:171 msgid "is required attribute by objectClass '%s': aliases: %s" msgstr "" #: lib/active_ldap/validations.rb:195 msgid "" msgstr "" #: lib/active_ldap/validations.rb:203 msgid "(%s) has invalid format: %s: required syntax: %s: %s" msgstr "" #: lib/active_ldap/validations.rb:205 msgid "has invalid format: %s: required syntax: %s: %s" msgstr "" #: lib/active_ldap/command.rb:16 msgid "Common options:" msgstr "" #: lib/active_ldap/command.rb:19 msgid "Specify configuration file written as YAML" msgstr "" #: lib/active_ldap/command.rb:26 msgid "Show this message" msgstr "" #: lib/active_ldap/command.rb:31 msgid "Show version" msgstr "" #: lib/active_ldap/base.rb:53 msgid "" "ActiveLdap::ConnectionNotEstablished has been deprecated since 1.1.0. Please " "use ActiveLdap::ConnectionNotSetup instead." msgstr "" #: lib/active_ldap/base.rb:131 msgid "invalid distinguished name (DN) to parse: %s" msgstr "" #: lib/active_ldap/base.rb:141 msgid "%s is invalid distinguished name (DN): %s" msgstr "" #: lib/active_ldap/base.rb:143 msgid "%s is invalid distinguished name (DN)" msgstr "" #: lib/active_ldap/base.rb:161 msgid "invalid LDIF: %s:" msgstr "" #: lib/active_ldap/base.rb:163 msgid "invalid LDIF:" msgstr "" #: lib/active_ldap/base.rb:241 msgid "LDAP configuration specifies nonexistent %s adapter" msgstr "" #: lib/active_ldap/base.rb:249 msgid "%s is unknown attribute" msgstr "" #: lib/active_ldap/base.rb:266 msgid "not implemented: %s" msgstr "" #: lib/active_ldap/base.rb:382 msgid "" "ActiveLdap::Base.establish_connection has been deprecated since 1.1.0. " "Please use ActiveLdap::Base.setup_connection instead." msgstr "" #: lib/active_ldap/base.rb:463 msgid "scope '%s' must be a Symbol" msgstr "" #: lib/active_ldap/base.rb:514 msgid "%s doesn't belong in a hierarchy descending from ActiveLdap" msgstr "" #: lib/active_ldap/base.rb:669 msgid "" "'%s' must be either nil, DN value as ActiveLdap::DN, String or Array or " "attributes as Hash" msgstr "" #: lib/active_ldap/base.rb:799 msgid "entry %s can't be saved" msgstr "" #: lib/active_ldap/base.rb:832 lib/active_ldap/base.rb:843 msgid "wrong number of arguments (%d for 1)" msgstr "" #: lib/active_ldap/base.rb:964 msgid "Can't find DN '%s' to reload" msgstr "" #: lib/active_ldap/base.rb:1369 msgid "%s's DN attribute (%s) isn't set" msgstr "" #: lib/active_ldap/attributes.rb:80 msgid "The first argument, name, must not be nil. Please report this as a bug!" msgstr "" #: lib/active_ldap/schema.rb:52 msgid "Unknown schema group: %s" msgstr "" #: lib/active_ldap/schema.rb:547 msgid "Attribute %s can only have a single value: %s" msgstr "" #: lib/active_ldap/schema.rb:566 msgid "Attribute %s: Hash must have one key-value pair only: %s" msgstr "" #: lib/active_ldap/connection.rb:98 msgid ":ldap_scope connection option is deprecated. Use :scope instead." msgstr "" #: lib/active_ldap/connection.rb:156 msgid "" "ActiveLdap::Connection.establish_connection has been deprecated since 1.1.0. " "Please use ActiveLdap::Connection.setup_connection instead." msgstr "" #: lib/active_ldap/connection.rb:236 msgid "since 1.1.0. " msgstr "" #: lib/active_ldap/user_password.rb:10 msgid "Invalid hashed password: %s" msgstr "" #: lib/active_ldap/user_password.rb:16 msgid "Unknown Hash type: %s" msgstr "" #: lib/active_ldap/user_password.rb:23 msgid "Can't extract salt from hashed password: %s" msgstr "" #: lib/active_ldap/user_password.rb:51 lib/active_ldap/user_password.rb:68 msgid "salt size must be == 4: %s" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:63 msgid "%s doesn't have the first \"'\"" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:67 msgid "%s doesn't have the last \"'B\"" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:71 msgid "%s has invalid character '%s'" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:108 msgid "%s should be TRUE or FALSE" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:121 msgid "%s should be just 2 printable characters" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:162 #: lib/active_ldap/schema/syntaxes.rb:381 msgid "%s has invalid UTF-8 character" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:237 msgid "%s has missing components: %s" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:240 msgid "%s is invalid time format" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:270 msgid "%s is invalid integer format" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:282 msgid "invalid JPEG format" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:323 msgid "%s is invalid numeric format" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:338 msgid "%s is invalid OID format: %s" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:340 msgid "%s is invalid OID format" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:353 msgid "%s has no mailbox type" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:357 msgid "%s has unprintable character in mailbox type: '%s'" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:362 msgid "%s has no mailbox" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:375 #: lib/active_ldap/schema/syntaxes.rb:394 msgid "empty string" msgstr "" #: lib/active_ldap/schema/syntaxes.rb:398 msgid "%s has unprintable character: '%s'" msgstr "" #: lib/active_ldap/get_text/parser.rb:96 msgid "Ignored '%{file}'. Solve dependencies first." msgstr "" #: lib/active_ldap/configuration.rb:70 msgid "%s connection is not configured" msgstr "" #: lib/active_ldap/configuration.rb:110 msgid ":ldap_scope configuration option is deprecated. Use :scope instead." msgstr "" #: lib/active_ldap/configuration.rb:131 msgid "invalid URI: %s" msgstr "" #: lib/active_ldap/configuration.rb:134 msgid "not a LDAP URI: %s" msgstr "" #: rails/init.rb:7 msgid "You need ActiveLdap %s or later" msgstr "" #: rails/init.rb:19 msgid "You should run 'script/generator scaffold_active_ldap' to make %s." msgstr "" #: benchmark/bench-al.rb:14 msgid "Specify prefix for benchmarking" msgstr "" #: benchmark/bench-al.rb:15 msgid "(default: %s)" msgstr "" #: benchmark/bench-al.rb:186 msgid "Populating..." msgstr "" #: benchmark/bench-al.rb:243 msgid "Entries processed by Ruby/ActiveLdap + LDAP: %d" msgstr "" #: benchmark/bench-al.rb:244 msgid "Entries processed by Ruby/ActiveLdap + Net::LDAP: %d" msgstr "" #: benchmark/bench-al.rb:246 msgid "" "Entries processed by Ruby/ActiveLdap + LDAP: (without object creation): %d" msgstr "" #: benchmark/bench-al.rb:249 msgid "" "Entries processed by Ruby/ActiveLdap + Net::LDAP: (without object creation): " "%d" msgstr "" #: benchmark/bench-al.rb:252 msgid "Entries processed by Ruby/LDAP: %d" msgstr "" #: benchmark/bench-al.rb:253 msgid "Entries processed by Net::LDAP: %d" msgstr "" #: benchmark/bench-al.rb:257 msgid "Cleaning..." msgstr "" activeldap-5.2.4/activeldap.gemspec0000644000004100000410000002516413464071751017367 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: activeldap 5.2.4 ruby lib Gem::Specification.new do |s| s.name = "activeldap".freeze s.version = "5.2.4" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Will Drewry".freeze, "Kouhei Sutou".freeze] s.date = "2019-04-26" s.description = " 'ActiveLdap' is a ruby library which provides a clean\n objected oriented interface to the Ruby/LDAP library. It was inspired\n by ActiveRecord. This is not nearly as clean or as flexible as\n ActiveRecord, but it is still trivial to define new objects and manipulate\n them with minimal difficulty.\n".freeze s.email = ["redpig@dataspill.org".freeze, "kou@cozmixng.org".freeze] s.files = [".yardopts".freeze, "COPYING".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.textile".freeze, "TODO".freeze, "benchmark/README.md".freeze, "benchmark/bench-backend.rb".freeze, "benchmark/bench-instantiate.rb".freeze, "benchmark/config.yaml.sample".freeze, "doc/text/development.textile".freeze, "doc/text/news.textile".freeze, "doc/text/rails.textile".freeze, "doc/text/tutorial.textile".freeze, "examples/config.yaml.example".freeze, "examples/example.der".freeze, "examples/example.jpg".freeze, "examples/groupadd".freeze, "examples/groupdel".freeze, "examples/groupls".freeze, "examples/groupmod".freeze, "examples/lpasswd".freeze, "examples/objects/group.rb".freeze, "examples/objects/ou.rb".freeze, "examples/objects/user.rb".freeze, "examples/ouadd".freeze, "examples/useradd".freeze, "examples/useradd-binary".freeze, "examples/userdel".freeze, "examples/userls".freeze, "examples/usermod".freeze, "examples/usermod-binary-add".freeze, "examples/usermod-binary-add-time".freeze, "examples/usermod-binary-del".freeze, "examples/usermod-lang-add".freeze, "lib/active_ldap.rb".freeze, "lib/active_ldap/acts/tree.rb".freeze, "lib/active_ldap/adapter/base.rb".freeze, "lib/active_ldap/adapter/jndi.rb".freeze, "lib/active_ldap/adapter/jndi_connection.rb".freeze, "lib/active_ldap/adapter/ldap.rb".freeze, "lib/active_ldap/adapter/ldap_ext.rb".freeze, "lib/active_ldap/adapter/net_ldap.rb".freeze, "lib/active_ldap/adapter/net_ldap_ext.rb".freeze, "lib/active_ldap/association/belongs_to.rb".freeze, "lib/active_ldap/association/belongs_to_many.rb".freeze, "lib/active_ldap/association/children.rb".freeze, "lib/active_ldap/association/collection.rb".freeze, "lib/active_ldap/association/has_many.rb".freeze, "lib/active_ldap/association/has_many_utils.rb".freeze, "lib/active_ldap/association/has_many_wrap.rb".freeze, "lib/active_ldap/association/proxy.rb".freeze, "lib/active_ldap/associations.rb".freeze, "lib/active_ldap/attribute_methods.rb".freeze, "lib/active_ldap/attribute_methods/before_type_cast.rb".freeze, "lib/active_ldap/attribute_methods/dirty.rb".freeze, "lib/active_ldap/attribute_methods/query.rb".freeze, "lib/active_ldap/attribute_methods/read.rb".freeze, "lib/active_ldap/attribute_methods/write.rb".freeze, "lib/active_ldap/attributes.rb".freeze, "lib/active_ldap/base.rb".freeze, "lib/active_ldap/callbacks.rb".freeze, "lib/active_ldap/command.rb".freeze, "lib/active_ldap/compatible.rb".freeze, "lib/active_ldap/configuration.rb".freeze, "lib/active_ldap/connection.rb".freeze, "lib/active_ldap/distinguished_name.rb".freeze, "lib/active_ldap/entry.rb".freeze, "lib/active_ldap/entry_attribute.rb".freeze, "lib/active_ldap/escape.rb".freeze, "lib/active_ldap/get_text.rb".freeze, "lib/active_ldap/get_text/parser.rb".freeze, "lib/active_ldap/helper.rb".freeze, "lib/active_ldap/human_readable.rb".freeze, "lib/active_ldap/ldap_controls.rb".freeze, "lib/active_ldap/ldap_error.rb".freeze, "lib/active_ldap/ldif.rb".freeze, "lib/active_ldap/log_subscriber.rb".freeze, "lib/active_ldap/object_class.rb".freeze, "lib/active_ldap/operations.rb".freeze, "lib/active_ldap/persistence.rb".freeze, "lib/active_ldap/populate.rb".freeze, "lib/active_ldap/railtie.rb".freeze, "lib/active_ldap/railties/controller_runtime.rb".freeze, "lib/active_ldap/schema.rb".freeze, "lib/active_ldap/schema/syntaxes.rb".freeze, "lib/active_ldap/supported_control.rb".freeze, "lib/active_ldap/user_password.rb".freeze, "lib/active_ldap/validations.rb".freeze, "lib/active_ldap/version.rb".freeze, "lib/active_ldap/xml.rb".freeze, "lib/rails/generators/active_ldap/model/USAGE".freeze, "lib/rails/generators/active_ldap/model/model_generator.rb".freeze, "lib/rails/generators/active_ldap/model/templates/model_active_ldap.rb".freeze, "lib/rails/generators/active_ldap/scaffold/scaffold_generator.rb".freeze, "lib/rails/generators/active_ldap/scaffold/templates/ldap.yml".freeze, "po/en/active-ldap.po".freeze, "po/ja/active-ldap.po".freeze, "test/add-phonetic-attribute-options-to-slapd.ldif".freeze, "test/al-test-utils.rb".freeze, "test/command.rb".freeze, "test/config.yaml.sample".freeze, "test/enable-start-tls.ldif".freeze, "test/fixtures/lower_case_object_class_schema.rb".freeze, "test/run-test.rb".freeze, "test/test_acts_as_tree.rb".freeze, "test/test_adapter.rb".freeze, "test/test_associations.rb".freeze, "test/test_attributes.rb".freeze, "test/test_base.rb".freeze, "test/test_base_per_instance.rb".freeze, "test/test_bind.rb".freeze, "test/test_callback.rb".freeze, "test/test_configuration.rb".freeze, "test/test_connection.rb".freeze, "test/test_connection_per_class.rb".freeze, "test/test_connection_per_dn.rb".freeze, "test/test_dirty.rb".freeze, "test/test_dn.rb".freeze, "test/test_entry.rb".freeze, "test/test_entry_attribute.rb".freeze, "test/test_find.rb".freeze, "test/test_groupadd.rb".freeze, "test/test_groupdel.rb".freeze, "test/test_groupls.rb".freeze, "test/test_groupmod.rb".freeze, "test/test_ldif.rb".freeze, "test/test_load.rb".freeze, "test/test_lpasswd.rb".freeze, "test/test_object_class.rb".freeze, "test/test_persistence.rb".freeze, "test/test_reflection.rb".freeze, "test/test_schema.rb".freeze, "test/test_supported_control.rb".freeze, "test/test_syntax.rb".freeze, "test/test_user.rb".freeze, "test/test_user_password.rb".freeze, "test/test_useradd-binary.rb".freeze, "test/test_useradd.rb".freeze, "test/test_userdel.rb".freeze, "test/test_userls.rb".freeze, "test/test_usermod-binary-add-time.rb".freeze, "test/test_usermod-binary-add.rb".freeze, "test/test_usermod-binary-del.rb".freeze, "test/test_usermod-lang-add.rb".freeze, "test/test_usermod.rb".freeze, "test/test_validation.rb".freeze] s.homepage = "http://activeldap.github.io/".freeze s.licenses = ["Ruby's".freeze, "GPLv2 or later".freeze] s.rubyforge_project = "ruby-activeldap".freeze s.rubygems_version = "2.5.2.1".freeze s.summary = "ActiveLdap is a object-oriented API to LDAP".freeze s.test_files = ["test/add-phonetic-attribute-options-to-slapd.ldif".freeze, "test/al-test-utils.rb".freeze, "test/command.rb".freeze, "test/config.yaml.sample".freeze, "test/enable-start-tls.ldif".freeze, "test/fixtures/lower_case_object_class_schema.rb".freeze, "test/run-test.rb".freeze, "test/test_acts_as_tree.rb".freeze, "test/test_adapter.rb".freeze, "test/test_associations.rb".freeze, "test/test_attributes.rb".freeze, "test/test_base.rb".freeze, "test/test_base_per_instance.rb".freeze, "test/test_bind.rb".freeze, "test/test_callback.rb".freeze, "test/test_configuration.rb".freeze, "test/test_connection.rb".freeze, "test/test_connection_per_class.rb".freeze, "test/test_connection_per_dn.rb".freeze, "test/test_dirty.rb".freeze, "test/test_dn.rb".freeze, "test/test_entry.rb".freeze, "test/test_entry_attribute.rb".freeze, "test/test_find.rb".freeze, "test/test_groupadd.rb".freeze, "test/test_groupdel.rb".freeze, "test/test_groupls.rb".freeze, "test/test_groupmod.rb".freeze, "test/test_ldif.rb".freeze, "test/test_load.rb".freeze, "test/test_lpasswd.rb".freeze, "test/test_object_class.rb".freeze, "test/test_persistence.rb".freeze, "test/test_reflection.rb".freeze, "test/test_schema.rb".freeze, "test/test_supported_control.rb".freeze, "test/test_syntax.rb".freeze, "test/test_user.rb".freeze, "test/test_user_password.rb".freeze, "test/test_useradd-binary.rb".freeze, "test/test_useradd.rb".freeze, "test/test_userdel.rb".freeze, "test/test_userls.rb".freeze, "test/test_usermod-binary-add-time.rb".freeze, "test/test_usermod-binary-add.rb".freeze, "test/test_usermod-binary-del.rb".freeze, "test/test_usermod-lang-add.rb".freeze, "test/test_usermod.rb".freeze, "test/test_validation.rb".freeze] if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, [">= 4.2"]) s.add_runtime_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) else s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 4.2"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) end else s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 4.2"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) end end