diff --git a/.build/README.md b/.build/README.md new file mode 100644 index 0000000..b4dede2 --- /dev/null +++ b/.build/README.md @@ -0,0 +1,3 @@ +# Build Files + +This folder contains various generic files related to build pipelines and jobs. diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..077a621 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,3 @@ +{ + "default": true +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..641aaea --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,32 @@ +# Changelog + + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] - + +### Added + +### Changed + +### Fixed + +### Removed + +## [0.1.0] - 2022-05-31 + +### Added + +- initial release of *OraDBA* documentation, tools and scripts. + +### Changed + +### Fixed + +### Removed + +[unreleased]: https://github.com/oehrlis/oradba +[0.1.0]: https://github.com/oehrlis/oradba \ No newline at end of file diff --git a/LICENSE b/LICENSE index 94a9ed0..261eeb9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,201 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. 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 -them 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 prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. 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. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey 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; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If 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 convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - 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. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -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. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - 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 -state 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 3 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, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program 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, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU 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 Lesser General -Public License instead of this License. But first, please read -. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index ad36604..dd596c8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,53 @@ -# ordba -Collection of scripts from oradba.ch +# OraDBA + + + +Welcome to the *OraDBA* a collection of scripts from [www.oradba.ch](https://www.oradba.ch/). This repository contains a couple of database administration scripts in *SQL* and *bash*. Among others it also includes a set of tools to maintain *Oracle Net Service* names resolution in *OpenLDAP*, *389DS* and *Oracle Unified Directory*. The project includes the documentation as well the corresponding script framework to setup and administer *Oracle Net Service* name in a *389 Directory Server* in particular. + +## Downloads and Latest Builds + +The official release documents are always attached to the pipelines as artifact. +See also the [release](https://github.com/oehrlis/oradba/releases) +page of this repository. + +Nightly Builds respectively builds on commit are attached as artifact to the +Azure DevOps pipeline. + +## Files and Folders + +- [bin](./bin/README.md) Scripts to administer and configure *Oracle Net Service* directory objects as well other *Database Administration* tasks. +- [doc](./doc/README.md) Markdown documentation files. +- [etc](./etc/README.md) Configuration files and templates for the *389 Directory Server* and the script framework. +- [images](./images/README.md) Images and logo files. +- [ldif](./ldif/README.md) *LDIF* files and templates to configure the *Oracle Context*. +- [log](./log/README.md) logfiles created by the script framework if not stored in *LOG_BASE* +- [CHANGELOG.md](./CHANGELOG.md) Change log for the *Markdown Doc Template*. +- [LICENSE](./LICENSE) License documentation. + +## Releases and Versions + +You find all official releases and release information on the Azure DevOps +project release page. As well documented in the [CHANGELOG.md](./CHANGELOG.md). + +The versioning and release tags follow the [semantic versioning](https://semver.org/). +A version number is specified by MAJOR.MINOR.PATCH, increase the: + +- *MAJOR* version when you make incompatible API changes, +- *MINOR* version when you add functionality in a backwards compatible manner, and +- *PATCH* version when you make backwards compatible bug fixes. + +Additional labels for pre-release and build metadata are available as extensions +to the MAJOR.MINOR.PATCH format. + +## How to Contribute + +It is highly recommended to take into account [AUTHOR_GUIDE.md](./AUTHOR_GUIDE.md) when contributing to this *Markdown Documentation*. However contributing covers the following steps. + +1. [Fork this respository](https://github.com/oehrlis/oradba/fork) +2. [Create a branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/), commit and publish your changes and enhancements +3. [Create a pull request](https://help.github.com/articles/creating-a-pull-request/) + +## License + +**OraDBA** is licensed under the Apache License 2.0. You may obtain a +copy of the License at . diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..b82608c --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +v0.1.0 diff --git a/bin/README.md b/bin/README.md new file mode 100644 index 0000000..306d6a9 --- /dev/null +++ b/bin/README.md @@ -0,0 +1,23 @@ +# Scripts and Tools + +This folder contains scripts and tools to administer TNS Names with OpenLDAP. +These are in particular: + +- [tns_add.sh](./tns_add.sh) Script to add an *Oracle Net Service Name* with + corresponding *Oracle Net Service Description* in one or more Base DN. +- [tns_delete.sh](./tns_delete.sh) Script to delete an *Oracle Net Service Name* + in one / more Base DN. +- [tns_dump.sh](./tns_dump.sh) Script to create a *tnsnames.ora* file for one / + more Base DN. +- [tns_functions.sh](./tns_functions.sh) common functions for the scripts. +- [tns_load.sh](./tns_load.sh) script to do bulk load one or more *tnsnames.ora* + files. +- [tns_modify.sh](./tns_modify.sh) Script to modify an *Oracle Net Service Name* + with corresponding *Net Service Description* in one or more Base DN. +- [tns_search.sh](./tns_search.sh) Script to search *Oracle Net Service Names* in + one or more Base DN. +- [tns_test.sh](./tns_test.sh) Script to test *Oracle Net Service Names* in one or + more base DN. The tests are done with *tnsping* and *sqlplus*. + +Full documentation of the scripts is available as part of the documentation. See +[Appendix C](../doc/9x93-Appendix-C_Scripts.md). diff --git a/bin/tns_add.sh b/bin/tns_add.sh new file mode 100755 index 0000000..2dd5085 --- /dev/null +++ b/bin/tns_add.sh @@ -0,0 +1,290 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tns_add.sh +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: Add a tns entry +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# - Customization ------------------------------------------------------------ +# - just add/update any kind of customized environment variable here + +# - End of Customization ---------------------------------------------------- + +# Define a bunch of bash option see +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o nounset # exit if script try to use an uninitialised variable +set -o errexit # exit script if any statement returns a non-true return value +set -o pipefail # pipefail exit after 1st piped commands failed + +# - Environment Variables --------------------------------------------------- +# define generic environment variables +VERSION=v0.1.0 +TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE:-"FALSE"} # enable verbose mode +TVDLDAP_DEBUG=${TVDLDAP_DEBUG:-"FALSE"} # enable debug mode +TVDLDAP_QUIET=${TVDLDAP_QUIET:-"FALSE"} # enable quiet mode +TVDLDAP_SCRIPT_NAME=$(basename ${BASH_SOURCE[0]}) +TVDLDAP_BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +TVDLDAP_LOG_DIR="$(dirname ${TVDLDAP_BIN_DIR})/log" + +# define logfile and logging +LOG_BASE=${LOG_BASE:-"${TVDLDAP_LOG_DIR}"} # Use script log directory as default logbase +TIMESTAMP=$(date "+%Y.%m.%d_%H%M%S") +readonly LOGFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$TIMESTAMP.log" +# - EOF Environment Variables ----------------------------------------------- + +# - Functions --------------------------------------------------------------- +# --------------------------------------------------------------------------- +# Function...: Usage +# Purpose....: Display Usage and exit script +# --------------------------------------------------------------------------- +function Usage() { + + # define default values for function arguments + error=${1:-"0"} # default error number + error_value=${2:-""} # default error message + cat << EOI + + Usage: ${TVDLDAP_SCRIPT_NAME} [options] [bind options] [add options] + + Common Options: + -m Usage this message + -v Enable verbose mode (default \$TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE}) + -d Enable debug mode (default \$TVDLDAP_DEBUG=${TVDLDAP_DEBUG}) + -b Specify Base DN to search Net Service Name. Either + specific base DN or ALL to search Net Service Name in + all available namingContexts. By the default the Base + DN is derived from a fully qualified Net Service Name. + Otherwise the default Base DN is taken from ldap.ora. Can + also be specified by setting TVDLDAP_BASEDN. + -h LDAP server (default take from ldap.ora). Can be specified + by setting TVDLDAP_LDAPHOST. + -p port on LDAP server (default take from ldap.ora). Can be + specified by setting TVDLDAP_LDAPPORT. + + Bind Options: + -D Bind DN (default ANONYMOUS). Can be specified by setting + TVDLDAP_BINDDN. + -w Bind password. Can be specified by setting TVDLDAP_BINDDN_PWD. + -W prompt for bind password. Can be specified by setting + TVDLDAP_BINDDN_PWDASK. + -y Read password from file. Can be specified by setting + TVDLDAP_BINDDN_PWDFILE. + + Add options: + -S Oracle Net Service Name to add (mandatory) + -N Oracle Net Service description string (mandatory) + -A Create an Oracle Net Service alias rather a full description + string. If this option is specified -N must just be a target + Oracle Net Service Name for the alias + -n Show what would be done but do not actually do it + -F Force mode to modify existing entry + + Configuration file: + The script does load configuration files to define default values as an + alternative for command line parameter. e.g. to set a bind DN TVDLDAP_BINDDN + LDAP hostname TVDLDAP_LDAPHOST, etc. The configuration files are loaded in + the following order: + + 1. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}.conf + 2. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}_custom.conf + 3. ${ETC_BASE}/${TOOL_BASE_NAME}.conf + 4. ${ETC_BASE}/${TOOL_BASE_NAME}_custom.conf + 5. Command line parameter + + Logfile : ${LOGFILE} + +EOI + dump_runtime_config # dump current tool specific environment in debug mode + clean_quit ${error} ${error_value} +} +# - EOF Functions ----------------------------------------------------------- + +# - Initialization ---------------------------------------------------------- +# initialize logfile +touch $LOGFILE 2>/dev/null +exec &> >(tee -a "$LOGFILE") # Open standard out at `$LOG_FILE` for write. +exec 2>&1 +echo "INFO : Start ${TVDLDAP_SCRIPT_NAME} on host $(hostname) at $(date)" + +# source common variables and functions from tns_functions.sh +if [ -f ${TVDLDAP_BIN_DIR}/tns_functions.sh ]; then + . ${TVDLDAP_BIN_DIR}/tns_functions.sh +else + echo "ERROR: Can not find common functions ${TVDLDAP_BIN_DIR}/tns_functions.sh" + exit 5 +fi + +load_config # load configuration files. File list in TVDLDAP_CONFIG_FILES + +# get options +while getopts mvdb:h:p:D:w:Wy:S:N:nFAE: CurOpt; do + case ${CurOpt} in + m) Usage 0;; + v) TVDLDAP_VERBOSE="TRUE" ;; + d) TVDLDAP_DEBUG="TRUE" ;; + b) TVDLDAP_BASEDN="${OPTARG}";; + h) TVDLDAP_LDAPHOST=${OPTARG};; + p) TVDLDAP_LDAPPORT=${OPTARG};; + D) TVDLDAP_BINDDN="${OPTARG}";; + w) TVDLDAP_BINDDN_PWD="${OPTARG}";; + W) TVDLDAP_BINDDN_PWDASK="TRUE";; + y) TVDLDAP_BINDDN_PWDFILE="${OPTARG}";; + F) TVDLDAP_FORCE="TRUE";; + n) TVDLDAP_DRYRUN="TRUE";; + A) TVDLDAP_NETALIAS="TRUE";; + S) NETSERVICE=${OPTARG};; + N) NETDESCSTRING="${OPTARG}";; + E) clean_quit "${OPTARG}";; + *) Usage 2 $*;; + esac +done + +# display usage and exit if parameter is null +if [ $# -eq 0 ]; then + Usage 1 +fi + +check_tools # check if we do have the required LDAP tools available +check_ldap_tools # check what kind of LDAP tools we do have e.g. + # OpenLDAP, Oracle DB or Oracle Unified Directory +dump_runtime_config # dump current tool specific environment in debug mode + +# get the ldapmodify and ldapadd options based on available tools +ldapmodify_options=$(ldapmodify_options) +ldapadd_command=$(ldapadd_command) +ldapadd_options=$(ldapadd_options) + +# Default values +export NETSERVICE=${NETSERVICE:-""} +export NETDESCSTRING=${NETDESCSTRING:-""} + +# check for mandatory parameters +if [ -z "${NETSERVICE}" ]; then clean_quit 3 "-S"; fi +if [ -z "${NETDESCSTRING}" ]; then clean_quit 3 "-N"; fi + +# get default values for LDAP Server +TVDLDAP_LDAPHOST=${TVDLDAP_LDAPHOST:-$(get_ldaphost)} +TVDLDAP_LDAPPORT=${TVDLDAP_LDAPPORT:-$(get_ldapport)} + +# get bind parameter +ask_bindpwd # ask for the bind password if TVDLDAP_BINDDN_PWDASK + # is TRUE and LDAP tools are not OpenLDAP +current_binddn=$(get_binddn_param "$TVDLDAP_BINDDN" ) +current_bindpwd=$(get_bindpwd_param "$TVDLDAP_BINDDN_PWD" ${TVDLDAP_BINDDN_PWDASK} "$TVDLDAP_BINDDN_PWDFILE") +if [ -z "$current_binddn" ] && [ -z "${current_bindpwd}" ]; then clean_quit 4; fi + +# get base DN information +BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") + +# Split Net Service Name if full qualified e.g. with a dot +current_basedn=$(split_net_service_basedn ${NETSERVICE}) +current_cn=$(split_net_service_cn ${NETSERVICE}) +# - EOF Initialization ------------------------------------------------------- + +# - Main --------------------------------------------------------------------- +echo_debug "DEBUG: Configuration / Variables:" +echo_debug "DEBUG: LDAP Host............... = $TVDLDAP_LDAPHOST" +echo_debug "DEBUG: LDAP Port............... = $TVDLDAP_LDAPPORT" +echo_debug "DEBUG: Bind DN................. = $TVDLDAP_BINDDN" +echo_debug "DEBUG: Bind PWD................ = $TVDLDAP_BINDDN_PWD" +echo_debug "DEBUG: Bind PWD File........... = $TVDLDAP_BINDDN_PWDFILE" +echo_debug "DEBUG: Bind parameter.......... = $current_binddn $current_bindpwd" +echo_debug "DEBUG: Base DN................. = $BASEDN_LIST" +echo_debug "DEBUG: Net Service Names....... = $NETSERVICE" +echo_debug "DEBUG: Net Service Name CN..... = $current_cn" +echo_debug "DEBUG: Net Service Name Base DN = $current_basedn" +echo_debug "DEBUG: Net Service Description. = $NETDESCSTRING" +echo_debug "DEBUG: Net Service Alias....... = $TVDLDAP_NETALIAS" +echo_debug "DEBUG: ldapmodify options...... = $ldapmodify_options" +echo_debug "DEBUG: ldapadd options......... = $ldapadd_options" + +# Set BASEDN_LIST to current Base DN from Net Service Name +if [ -n "${current_basedn}" ]; then BASEDN_LIST=${current_basedn}; fi + +# loop over base DN +for basedn in ${BASEDN_LIST}; do + echo_debug "DEBUG: Process base dn $basedn" + if ! net_service_exists "$current_cn" "${basedn}" ; then + echo "INFO : Add Net Service Name $current_cn in $basedn" + if ! dryrun_enabled; then + if ! alias_enabled; then + $ldapadd_command -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapadd_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$basedn +objectclass: top +objectclass: orclNetService +cn: $current_cn +orclNetDescString: $NETDESCSTRING + +EOI + else + aliasedObjectName=$(split_net_service_cn ${NETDESCSTRING}) + $ldapadd_command -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapadd_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$basedn +aliasedObjectName: cn=$aliasedObjectName,cn=OracleContext,$basedn +objectClass: alias +objectClass: top +objectClass: orclNetServiceAlias +cn: $current_cn + +EOI + fi + + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "$ldapadd_command"; fi + else + echo "INFO : Dry run enabled, skip add Net Service Name $current_cn in $basedn" + fi + else + if force_enabled; then + echo "INFO : Modify Net Service Name $current_cn in $current_basedn" + if ! dryrun_enabled; then + if ! alias_enabled; then + ldapmodify -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapmodify_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$current_basedn +changetype: modify +replace: orclNetDescString +orclNetDescString: $NETDESCSTRING + +EOI + else + aliasedObjectName=$(split_net_service_cn ${NETDESCSTRING}) + ldapmodify -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapmodify_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$current_basedn +changetype: modify +replace: aliasedObjectName +aliasedObjectName: cn=$aliasedObjectName,cn=OracleContext,$basedn + +EOI + fi + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "ldapmodify"; fi + else + echo "INFO : Dry run enabled, skip modify Net Service Name $current_cn in $basedn" + fi + else + echo "WARN : Net Service Name $current_cn does exists in $current_basedn. Enable force mode to modify it." + fi + fi +done + +rotate_logfiles # purge log files based on TVDLDAP_KEEP_LOG_DAYS +clean_quit # clean exit with return code 0 +# --- EOF -------------------------------------------------------------------- diff --git a/bin/tns_delete.sh b/bin/tns_delete.sh new file mode 100755 index 0000000..2753e65 --- /dev/null +++ b/bin/tns_delete.sh @@ -0,0 +1,243 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tns_delete.sh +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: Delete a tns entry +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# - Customization ------------------------------------------------------------ +# - just add/update any kind of customized environment variable here + +# - End of Customization ---------------------------------------------------- + +# Define a bunch of bash option see +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o nounset # exit if script try to use an uninitialised variable +set -o errexit # exit script if any statement returns a non-true return value +set -o pipefail # pipefail exit after 1st piped commands failed + +# - Environment Variables --------------------------------------------------- +# define generic environment variables +VERSION=v0.1.0 +TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE:-"FALSE"} # enable verbose mode +TVDLDAP_DEBUG=${TVDLDAP_DEBUG:-"FALSE"} # enable debug mode +TVDLDAP_QUIET=${TVDLDAP_QUIET:-"FALSE"} # enable quiet mode +TVDLDAP_SCRIPT_NAME=$(basename ${BASH_SOURCE[0]}) +TVDLDAP_BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +TVDLDAP_LOG_DIR="$(dirname ${TVDLDAP_BIN_DIR})/log" + +# define logfile and logging +LOG_BASE=${LOG_BASE:-"${TVDLDAP_LOG_DIR}"} # Use script log directory as default logbase +TIMESTAMP=$(date "+%Y.%m.%d_%H%M%S") +readonly LOGFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$TIMESTAMP.log" +# - EOF Environment Variables ----------------------------------------------- + +# - Functions --------------------------------------------------------------- +# --------------------------------------------------------------------------- +# Function...: Usage +# Purpose....: Display Usage and exit script +# --------------------------------------------------------------------------- +function Usage() { + + # define default values for function arguments + error=${1:-"0"} # default error number + error_value=${2:-""} # default error message + cat << EOI + + Usage: ${TVDLDAP_SCRIPT_NAME} [options] [bind options] [delete options] [services] + + where: + services Comma separated list of Oracle Net Service Names to delete + + Common Options: + -m Usage this message + -v Enable verbose mode (default \$TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE}) + -d Enable debug mode (default \$TVDLDAP_DEBUG=${TVDLDAP_DEBUG}) + -b Specify Base DN to search Net Service Name. Either + specific base DN or ALL to search Net Service Name in + all available namingContexts. By the default the Base + DN is derived from a fully qualified Net Service Name. + Otherwise the default Base DN is taken from ldap.ora. Can + also be specified by setting TVDLDAP_BASEDN. + -h LDAP server (default take from ldap.ora). Can be specified + by setting TVDLDAP_LDAPHOST. + -p port on LDAP server (default take from ldap.ora). Can be + specified by setting TVDLDAP_LDAPPORT. + + Bind Options: + -D Bind DN (default ANONYMOUS). Can be specified by setting + TVDLDAP_BINDDN. + -w Bind password. Can be specified by setting TVDLDAP_BINDDN_PWD. + -W prompt for bind password. Can be specified by setting + TVDLDAP_BINDDN_PWDASK. + -y Read password from file. Can be specified by setting + TVDLDAP_BINDDN_PWDFILE. + + Delete options: + -S Oracle Net Service Names to delete (mandatory) + -n Show what would be done but do not actually do it + -F Force mode to modify existing entry + + Configuration file: + The script does load configuration files to define default values as an + alternative for command line parameter. e.g. to set a bind DN TVDLDAP_BINDDN + LDAP hostname TVDLDAP_LDAPHOST, etc. The configuration files are loaded in + the following order: + + 1. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}.conf + 2. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}_custom.conf + 3. ${ETC_BASE}/${TOOL_BASE_NAME}.conf + 4. ${ETC_BASE}/${TOOL_BASE_NAME}_custom.conf + 5. Command line parameter + + Logfile : ${LOGFILE} + +EOI + dump_runtime_config # dump current tool specific environment in debug mode + clean_quit ${error} ${error_value} +} +# - EOF Functions ----------------------------------------------------------- + +# - Initialization ---------------------------------------------------------- +# initialize logfile +touch $LOGFILE 2>/dev/null +exec &> >(tee -a "$LOGFILE") # Open standard out at `$LOG_FILE` for write. +exec 2>&1 +echo "INFO : Start ${TVDLDAP_SCRIPT_NAME} on host $(hostname) at $(date)" + +# source common variables and functions from tns_functions.sh +if [ -f ${TVDLDAP_BIN_DIR}/tns_functions.sh ]; then + . ${TVDLDAP_BIN_DIR}/tns_functions.sh +else + echo "ERROR: Can not find common functions ${TVDLDAP_BIN_DIR}/tns_functions.sh" + exit 5 +fi + +load_config # load configuration files. File list in TVDLDAP_CONFIG_FILES + +# get options +while getopts mvdb:h:p:D:w:Wy:S:nFE: CurOpt; do + case ${CurOpt} in + m) Usage 0;; + v) TVDLDAP_VERBOSE="TRUE" ;; + d) TVDLDAP_DEBUG="TRUE" ;; + b) TVDLDAP_BASEDN="${OPTARG}";; + h) TVDLDAP_LDAPHOST=${OPTARG};; + p) TVDLDAP_LDAPPORT=${OPTARG};; + D) TVDLDAP_BINDDN="${OPTARG}";; + w) TVDLDAP_BINDDN_PWD="${OPTARG}";; + W) TVDLDAP_BINDDN_PWDASK="TRUE";; + y) TVDLDAP_BINDDN_PWDFILE="${OPTARG}";; + F) TVDLDAP_FORCE="TRUE";; + n) TVDLDAP_DRYRUN="TRUE";; + S) NETSERVICE=${OPTARG};; + E) clean_quit "${OPTARG}";; + *) Usage 2 $*;; + esac +done + +# display usage and exit if parameter is null +if [ $# -eq 0 ]; then + Usage 1 +fi + +check_tools # check if we do have the required LDAP tools available +check_ldap_tools # check what kind of LDAP tools we do have e.g. + # OpenLDAP, Oracle DB or Oracle Unified Directory +dump_runtime_config # dump current tool specific environment in debug mode + +# get the ldapsearch options based on available tools +ldapsearch_options=$(ldapsearch_options) + +# Default values +export NETSERVICE=${NETSERVICE:-""} + +# check for Service and Arguments +if [ -z "$NETSERVICE" ] && [ $# -ne 0 ]; then + if [[ "$1" =~ ^-.* ]]; then + NETSERVICE=$ORACLE_SID # default service to ORACLE_SID if Argument starting with dash + else + NETSERVICE=$1 # default service to Argument if not starting with dash + fi +fi + +# check for mandatory parameters +if [ -z "${NETSERVICE}" ]; then clean_quit 3 "-S"; fi + +# get default values for LDAP Server +TVDLDAP_LDAPHOST=${TVDLDAP_LDAPHOST:-$(get_ldaphost)} +TVDLDAP_LDAPPORT=${TVDLDAP_LDAPPORT:-$(get_ldapport)} + +# get bind parameter +ask_bindpwd # ask for the bind password if TVDLDAP_BINDDN_PWDASK + # is TRUE and LDAP tools are not OpenLDAP +current_binddn=$(get_binddn_param "$TVDLDAP_BINDDN" ) +current_bindpwd=$(get_bindpwd_param "$TVDLDAP_BINDDN_PWD" ${TVDLDAP_BINDDN_PWDASK} "$TVDLDAP_BINDDN_PWDFILE") +if [ -z "$current_binddn" ] && [ -z "${current_bindpwd}" ]; then clean_quit 4; fi + +# get base DN information +BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") +# - EOF Initialization ------------------------------------------------------- + +# - Main --------------------------------------------------------------------- +echo_debug "DEBUG: Configuration / Variables:" +echo_debug "DEBUG: LDAP Host............... = $TVDLDAP_LDAPHOST" +echo_debug "DEBUG: LDAP Port............... = $TVDLDAP_LDAPPORT" +echo_debug "DEBUG: Bind DN................. = $TVDLDAP_BINDDN" +echo_debug "DEBUG: Bind PWD................ = $TVDLDAP_BINDDN_PWD" +echo_debug "DEBUG: Bind PWD File........... = $TVDLDAP_BINDDN_PWDFILE" +echo_debug "DEBUG: Bind parameter.......... = $current_binddn $current_bindpwd" +echo_debug "DEBUG: Base DN................. = $BASEDN_LIST" +echo_debug "DEBUG: Net Service Names....... = $NETSERVICE" +echo_debug "DEBUG: ldapsearch options...... = $ldapsearch_options" + +for service in $(echo $NETSERVICE | tr "," "\n"); do # loop over service + echo_debug "DEBUG: process service $service" + current_basedn=$(split_net_service_basedn ${service}) + current_cn=$(split_net_service_cn ${service}) + + # Set BASEDN_LIST to current Base DN from Net Service Name + if [ -n "${current_basedn}" ]; then + BASEDN_LIST=${current_basedn} + else + BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") + fi + echo_debug "DEBUG: current Base DN list = $BASEDN_LIST" + echo_debug "DEBUG: current Net Service Names = $current_cn" + + # loop over base DN + for basedn in ${BASEDN_LIST}; do + if basedn_exists ${basedn}; then + echo_debug "DEBUG: Process base dn $basedn" + if net_service_exists "$current_cn" "${basedn}" ; then + echo "INFO : Delete Net Service Name $current_cn in $basedn" + if ! dryrun_enabled; then + ldapdelete -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} ${current_bindpwd} \ + "cn=$current_cn,cn=OracleContext,$basedn" + + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "ldapdelete"; fi + else + echo "INFO : Dry run enabled, skip delete Net Service Name $current_cn in $basedn" + fi + else + echo "WARN : Net Service Name $current_cn does not exists in $current_basedn." + fi + fi + done +done + +rotate_logfiles # purge log files based on TVDLDAP_KEEP_LOG_DAYS +clean_quit # clean exit with return code 0 +# --- EOF -------------------------------------------------------------------- diff --git a/bin/tns_dump.sh b/bin/tns_dump.sh new file mode 100755 index 0000000..cc1b434 --- /dev/null +++ b/bin/tns_dump.sh @@ -0,0 +1,307 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tns_dump.sh +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: Dump entries as tnsnames.ora +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# - Customization ------------------------------------------------------------ +# - just add/update any kind of customized environment variable here +DEFAULT_OUTPUT_DIR=$TNS_ADMIN +DEFAULT_FILE_PREFIX="ldap_dump" +# - End of Customization ---------------------------------------------------- + +# Define a bunch of bash option see +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o nounset # exit if script try to use an uninitialised variable +set -o errexit # exit script if any statement returns a non-true return value +set -o pipefail # pipefail exit after 1st piped commands failed + +# - Environment Variables --------------------------------------------------- +# define generic environment variables +VERSION=v0.1.0 +TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE:-"FALSE"} # enable verbose mode +TVDLDAP_DEBUG=${TVDLDAP_DEBUG:-"FALSE"} # enable debug mode +TVDLDAP_QUIET=${TVDLDAP_QUIET:-"FALSE"} # enable quiet mode +TVDLDAP_SCRIPT_NAME=$(basename ${BASH_SOURCE[0]}) +TVDLDAP_BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +TVDLDAP_LOG_DIR="$(dirname ${TVDLDAP_BIN_DIR})/log" + +# define logfile and logging +LOG_BASE=${LOG_BASE:-"${TVDLDAP_LOG_DIR}"} # Use script log directory as default logbase +TIMESTAMP=$(date "+%Y.%m.%d_%H%M%S") +readonly LOGFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$TIMESTAMP.log" + +# define tempfile for ldapsearch +TEMPFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$$.ldif" +# - EOF Environment Variables ----------------------------------------------- + +# - Functions --------------------------------------------------------------- +# --------------------------------------------------------------------------- +# Function...: Usage +# Purpose....: Display Usage and exit script +# --------------------------------------------------------------------------- +function Usage() { + + # define default values for function arguments + error=${1:-"0"} # default error number + error_value=${2:-""} # default error message + cat << EOI + + Usage: ${TVDLDAP_SCRIPT_NAME} [options] [bind options] [dump options] [search options] [services] + + Common Options: + -m Usage this message + -v Enable verbose mode (default \$TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE}) + -d Enable debug mode (default \$TVDLDAP_DEBUG=${TVDLDAP_DEBUG}) + -b Specify Base DN to search Net Service Name. Either + specific base DN or ALL to search Net Service Name in + all available namingContexts. By the default the Base + DN is derived from a fully qualified Net Service Name. + Otherwise the default Base DN is taken from ldap.ora. Can + also be specified by setting TVDLDAP_BASEDN. + -h LDAP server (default take from ldap.ora). Can be specified + by setting TVDLDAP_LDAPHOST. + -p port on LDAP server (default take from ldap.ora). Can be + specified by setting TVDLDAP_LDAPPORT. + + Bind Options: + -D Bind DN (default ANONYMOUS). Can be specified by setting + TVDLDAP_BINDDN. + -w Bind password. Can be specified by setting TVDLDAP_BINDDN_PWD. + -W prompt for bind password. Can be specified by setting + TVDLDAP_BINDDN_PWDASK. + -y Read password from file. Can be specified by setting + TVDLDAP_BINDDN_PWDFILE. + + Search options: + -S Oracle Net Service Names to search for + (default \$ORACLE_SID) + + Dump options: + -T Output Directory to dump the tnsnames information + (default $DEFAULT_OUTPUT_DIR) + -o Output file with tnsnames dump from specified Base + DN (default ${DEFAULT_FILE_PREFIX}__.ora) + -n Show what would be done but do not actually do it + -F Force mode to overwrite existing tnsnames dump files + + Configuration file: + The script does load configuration files to define default values as an + alternative for command line parameter. e.g. to set a bind DN TVDLDAP_BINDDN + LDAP hostname TVDLDAP_LDAPHOST, etc. The configuration files are loaded in + the following order: + + 1. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}.conf + 2. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}_custom.conf + 3. ${ETC_BASE}/${TOOL_BASE_NAME}.conf + 4. ${ETC_BASE}/${TOOL_BASE_NAME}_custom.conf + 5. Command line parameter + + Logfile : ${LOGFILE} + +EOI + dump_runtime_config # dump current tool specific environment in debug mode + clean_quit ${error} ${error_value} +} +# - EOF Functions ----------------------------------------------------------- + +# - Initialization ---------------------------------------------------------- +touch $LOGFILE 2>/dev/null # initialize logfile +exec &> >(tee -a "$LOGFILE") # Open standard out at `$LOG_FILE` for write. +exec 2>&1 +echo "INFO : Start ${TVDLDAP_SCRIPT_NAME} on host $(hostname) at $(date)" + +# source common variables and functions from tns_functions.sh +if [ -f ${TVDLDAP_BIN_DIR}/tns_functions.sh ]; then + . ${TVDLDAP_BIN_DIR}/tns_functions.sh +else + echo "ERROR: Can not find common functions ${TVDLDAP_BIN_DIR}/tns_functions.sh" + exit 5 +fi + +load_config # load configur26ation files. File list in TVDLDAP_CONFIG_FILES + +# initialize tempfile for ldapsearch output +touch $TEMPFILE 2>/dev/null || clean_quit 25 $TEMPFILE + +# get options +while getopts mvdb:h:p:D:w:Wy:o:T:FE:S: CurOpt; do + case ${CurOpt} in + m) Usage 0;; + v) TVDLDAP_VERBOSE="TRUE" ;; + d) TVDLDAP_DEBUG="TRUE" ;; + b) TVDLDAP_BASEDN="${OPTARG}";; + h) TVDLDAP_LDAPHOST=${OPTARG};; + p) TVDLDAP_LDAPPORT=${OPTARG};; + D) TVDLDAP_BINDDN="${OPTARG}";; + w) TVDLDAP_BINDDN_PWD="${OPTARG}";; + W) TVDLDAP_BINDDN_PWDASK="TRUE";; + y) TVDLDAP_BINDDN_PWDFILE="${OPTARG}";; + T) OUTPUT_DIR="${OPTARG}";; + o) OUTPUT_FILE="${OPTARG}";; + F) TVDLDAP_FORCE="TRUE";; + S) NETSERVICE=${OPTARG};; + E) clean_quit "${OPTARG}";; + *) Usage 2 $*;; + esac +done + +check_tools # check if we do have the required LDAP tools available +check_ldap_tools # check what kind of LDAP tools we do have e.g. + # OpenLDAP, Oracle DB or Oracle Unified Directory +dump_runtime_config # dump current tool specific environment in debug mode + +# get the ldapsearch options based on available tools +ldapsearch_options=$(ldapsearch_options) + +# Default values +OUTPUT_DIR=${OUTPUT_DIR:-$DEFAULT_OUTPUT_DIR} +OUTPUT_FILE=${OUTPUT_FILE:-""} + +# Default values +export NETSERVICE=${NETSERVICE:-""} + +# check for Service and Arguments +if [ -z "$NETSERVICE" ] && [ $# -ne 0 ]; then + echo_debug "DEBUG: Process default NETSERVICE" + if [[ "$1" =~ ^-.* ]]; then + echo_debug "DEBUG: Set NETSERVICE to ALL" + NETSERVICE="ALL" # default service to * if Argument starting with dash + else + echo_debug "DEBUG: Set NETSERVICE to $1" + NETSERVICE=$1 # default service to Argument if not starting with dash + fi +else + echo_debug "DEBUG: Set NETSERVICE to ALL" + NETSERVICE=${NETSERVICE:-"ALL"} +fi + +# get default values for LDAP Server +TVDLDAP_LDAPHOST=${TVDLDAP_LDAPHOST:-$(get_ldaphost)} +TVDLDAP_LDAPPORT=${TVDLDAP_LDAPPORT:-$(get_ldapport)} + +# get bind parameter +ask_bindpwd # ask for the bind password if TVDLDAP_BINDDN_PWDASK + # is TRUE and LDAP tools are not OpenLDAP +current_binddn=$(get_binddn_param "$TVDLDAP_BINDDN" ) +current_bindpwd=$(get_bindpwd_param "$TVDLDAP_BINDDN_PWD" ${TVDLDAP_BINDDN_PWDASK} "$TVDLDAP_BINDDN_PWDFILE") +if [ -n "$current_binddn" ] && [ -z "${current_bindpwd}" ]; then clean_quit 4; fi + +# get base DN information +BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") + +# check if we can write output +if [ ! -w "${OUTPUT_DIR}" ]; then + clean_quit 21 "${OUTPUT_DIR}" +fi + +# Check if output already does exists +if [ -n "$OUTPUT_FILE" ]; then + OUTPUT_FILE=$(basename "$OUTPUT_FILE") + if [ -f "${OUTPUT_DIR}/${OUTPUT_FILE}" ] && ! force_enabled; then + clean_quit 20 "${OUTPUT_DIR}/${OUTPUT_FILE}" + elif [ -f "${OUTPUT_DIR}/${OUTPUT_FILE}" ] && force_enabled; then + rm ${OUTPUT_DIR}/${OUTPUT_FILE} + fi +fi +# - EOF Initialization ------------------------------------------------------- + +# - Main --------------------------------------------------------------------- +echo_debug "DEBUG: Configuration / Variables:" +echo_debug "DEBUG: LDAP Host............... = $TVDLDAP_LDAPHOST" +echo_debug "DEBUG: LDAP Port............... = $TVDLDAP_LDAPPORT" +echo_debug "DEBUG: Bind DN................. = $TVDLDAP_BINDDN" +echo_debug "DEBUG: Bind PWD................ = $TVDLDAP_BINDDN_PWD" +echo_debug "DEBUG: Bind PWD File........... = $TVDLDAP_BINDDN_PWDFILE" +echo_debug "DEBUG: Bind parameter.......... = $current_binddn $current_bindpwd" +echo_debug "DEBUG: Base DN................. = $BASEDN_LIST" +echo_debug "DEBUG: Net Service Names....... = $NETSERVICE" +echo_debug "DEBUG: Output directory........ = $OUTPUT_DIR" +echo_debug "DEBUG: Output file............. = $OUTPUT_FILE" +echo_debug "DEBUG: ldapsearch options...... = $ldapsearch_options" + +for service in $(echo $NETSERVICE | tr "," "\n"); do # loop over service + echo_debug "DEBUG: process service $service" + # set current_cn to * for all + if [ "${NETSERVICE^^}" == "ALL" ]; then + current_basedn="" + current_cn="*" + echo_debug "DEBUG: current Net Service Names = $NETSERVICE" + else + current_basedn=$(split_net_service_basedn ${service}) + current_cn=$(split_net_service_cn ${service}) + echo_debug "DEBUG: current Net Service Names = $current_cn" + fi + + # Set BASEDN_LIST to current Base DN taken from Net Service Name + if [ -n "${current_basedn}" ]; then + BASEDN_LIST=${current_basedn} + else + BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") + fi + + echo_debug "DEBUG: current Base DN list........ = $BASEDN_LIST" + for basedn in ${BASEDN_LIST}; do # loop over base DN + if basedn_exists ${basedn}; then + echo "INFO : Process base dn $basedn" + domain=$(echo $basedn|sed -e 's/,dc=/\./g' -e 's/dc=//g') + if [ -z "$OUTPUT_FILE" ]; then + dump_file="${DEFAULT_FILE_PREFIX}_${domain}_${TIMESTAMP}.ora" + else + dump_file=$OUTPUT_FILE + fi + + echo "INFO : Dump Net Service Names from $basedn to ${OUTPUT_DIR}/${dump_file}" + echo "# LDAP Net Service Description dump for base DN ${basedn}" >>${OUTPUT_DIR}/${dump_file} + echo "# Dump Date : $(date)" >>${OUTPUT_DIR}/${dump_file} + if ! alias_enabled; then + # run ldapsearch an write output to tempfile + ldapsearch -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} ${current_bindpwd} \ + ${ldapsearch_options} -b "$basedn" -s sub \ + "(&(cn=${current_cn})(|(objectClass=orclNetService)(objectClass=orclService)(objectClass=orclNetServiceAlias)))" \ + cn orclNetDescString aliasedObjectName>$TEMPFILE + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "ldapsearch"; fi + fi + # check if tempfile does exist and has some values + if [ -s "$TEMPFILE" ] ; then + echo "" >> $TEMPFILE # add a new line to the tempfile + # loop over ldapsearch results + for result in $(grep -iv '^dn: ' $TEMPFILE | sed -n '1 {h; $ !d}; $ {x; s/\n //g; p}; /^ / {H; d}; /^ /! {x; s/\n //g; p}'| sed 's/$/;/g' | sed 's/^;$/DELIM/g' | tr -d '\n'| sed 's/DELIM/\n/g'|tr -d ' '); do + echo_debug "DEBUG: ${result}" + cn=$(echo ${result}| cut -d ';' -f 1 | cut -d " " -f 2 | sed 's/cn://gi') + # check for aliasedObjectName or orclNetDescString + if [[ "$result" == *orclNetDescString* ]]; then + NetDescString=$(echo ${result}| cut -d ';' -f 2 | cut -d " " -f2- |sed 's/orclNetDescString://gi') + echo "${cn}.${domain}=${NetDescString}" >>${OUTPUT_DIR}/${dump_file} + elif [[ "$result" == *aliasedObjectName* ]]; then + aliasedObjectName=$(echo ${result}| cut -d ';' -f 2 | cut -d " " -f2- |sed 's/aliasedObjectName://gi') + echo "# ${cn}.${domain} alias to ${aliasedObjectName}" >>${OUTPUT_DIR}/${dump_file} + fi + done + else + echo "WARN : No Net Service Name / Alias found in ${basedn}" + echo "# No Net Service Name / Alias found in ${basedn}" >>${OUTPUT_DIR}/${dump_file} + fi + echo >>${OUTPUT_DIR}/${dump_file} + else + echo "WARN : Base DN ${basedn} not found" + fi + done +done + +rotate_logfiles # purge log files based on TVDLDAP_KEEP_LOG_DAYS +clean_quit # clean exit with return code 0 +# --- EOF -------------------------------------------------------------------- diff --git a/bin/tns_functions.sh b/bin/tns_functions.sh new file mode 100755 index 0000000..0cee06b --- /dev/null +++ b/bin/tns_functions.sh @@ -0,0 +1,606 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tns_functions.sh +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: Common functions used by the TNS bash scripts. +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- + +# - Customization ------------------------------------------------------------ +# - just add/update any kind of customized environment variable here +TVDLDAP_DEFAULT_LDAPHOST="localhost" +TVDLDAP_DEFAULT_LDAPPORT=389 +TVDLDAP_DEFAULT_KEEP_LOG_DAYS=5 +TVDLDAP_DEFAULT_BASEDN="" +TVDLDAP_DEFAULT_BINDDN="" +TVDLDAP_DEFAULT_BINDDN_PWDASK="FALSE" +TVDLDAP_DEFAULT_BINDDN_PWD="" +TVDLDAP_DEFAULT_BINDDN_PWDFILE="" +TVDLDAP_DEFAULT_TIMEMOUT=0 +TVDLDAP_DEFAULT_SQL_USER="" +TVDLDAP_DEFAULT_SQL_PWD="" +TVDLDAP_DEFAULT_SQL_PWDASK="FALSE" +TVDLDAP_DEFAULT_SQL_PWDFILE="" +TVDLDAP_DEFAULT_LDAPTOOLS="" +# - End of Customization ---------------------------------------------------- + +# Define a bunch of bash option see +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o nounset # exit if script try to use an uninitialised variable +set -o errexit # exit script if any statement returns a non-true return value +set -o pipefail # pipefail exit after 1st piped commands failed + +# - Environment Variables --------------------------------------------------- +# define generic environment variables +VERSION=v0.1.0 +TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE:-"FALSE"} # enable verbose mode +TVDLDAP_DEBUG=${TVDLDAP_DEBUG:-"FALSE"} # enable debug mode +TVDLDAP_QUIET=${TVDLDAP_QUIET:-"FALSE"} # enable quiet mode +DEFAULT_TOOLS=${DEFAULT_TOOLS:-"ldapsearch ldapmodify ldapdelete"} # List of default tools +TEMPFILE=${TEMPFILE:-""} +TNSPING_TEMPFILE=${TNSPING_TEMPFILE:-""} +LOCAL_SCRIPT_NAME=$(basename ${BASH_SOURCE[0]}) +export TVDLDAP_BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +export TVDLDAP_LOG_DIR="$(dirname ${TVDLDAP_BIN_DIR})/log" +export TVDLDAP_ETC_DIR="$(dirname ${TVDLDAP_BIN_DIR})/etc" +export TVDLDAP_BASE=$(dirname ${TVDLDAP_BIN_DIR}) +export TOOL_BASE_NAME=$(basename ${TVDLDAP_BASE}) +export TVDLDAP_CONFIG_FILES="" +export TVDLDAP_KEEP_LOG_DAYS=${TVDLDAP_KEEP_LOG_DAYS:-$TVDLDAP_DEFAULT_KEEP_LOG_DAYS} +padding='............................' + +# define bind DN environment variables +export TVDLDAP_LDAPTOOLS=${TVDLDAP_LDAPTOOLS:-$TVDLDAP_DEFAULT_LDAPTOOLS} +export TVDLDAP_BASEDN=${TVDLDAP_BASEDN:-$TVDLDAP_DEFAULT_BASEDN} +export TVDLDAP_BINDDN=${TVDLDAP_BINDDN:-$TVDLDAP_DEFAULT_BINDDN} +export TVDLDAP_BINDDN_PWDASK=${TVDLDAP_BINDDN_PWDASK:-$TVDLDAP_DEFAULT_BINDDN_PWDASK} +export TVDLDAP_BINDDN_PWD=${TVDLDAP_BINDDN_PWD:-$TVDLDAP_DEFAULT_BINDDN_PWD} +export TVDLDAP_BINDDN_PWDFILE=${TVDLDAP_BINDDN_PWDFILE:-$TVDLDAP_DEFAULT_BINDDN_PWDFILE} + +# define SQLPlus test credential environment variables +export TVDLDAP_SQL_USER=${TVDLDAP_SQL_USER:-$TVDLDAP_DEFAULT_SQL_USER} +export TVDLDAP_SQL_PWDASK=${TVDLDAP_SQL_PWDASK:-$TVDLDAP_DEFAULT_SQL_PWDASK} +export TVDLDAP_SQL_PWD=${TVDLDAP_SQL_PWD:-$TVDLDAP_DEFAULT_SQL_PWD} +export TVDLDAP_SQL_PWDFILE=${TVDLDAP_SQL_PWDFILE:-$TVDLDAP_DEFAULT_SQL_PWDFILE} + +# define default timeout +export TVDLDAP_TIMEMOUT=${TVDLDAP_TIMEMOUT:-$TVDLDAP_DEFAULT_TIMEMOUT} + +# initialize common variables +export TVDLDAP_DRYRUN=${TVDLDAP_DRYRUN:-"FALSE"} +export TVDLDAP_FORCE=${TVDLDAP_FORCE:-"FALSE"} +export TVDLDAP_NETALIAS=${TVDLDAP_NETALIAS:-"FALSE"} +# - EOF Environment Variables ----------------------------------------------- + +# - Functions --------------------------------------------------------------- +# --------------------------------------------------------------------------- +# Function...: force_enabled +# Purpose....: Check if FORCE mode is enabled +# --------------------------------------------------------------------------- +function force_enabled () { + if [ "${TVDLDAP_FORCE^^}" == "TRUE" ]; then + return 0 + else + return 1 + fi +} + +# --------------------------------------------------------------------------- +# Function...: alias_enabled +# Purpose....: Check if FORCE mode is enabled +# --------------------------------------------------------------------------- +function alias_enabled () { + if [ "${TVDLDAP_NETALIAS^^}" == "TRUE" ]; then + return 0 + else + return 1 + fi +} + +# --------------------------------------------------------------------------- +# Function...: dryrun_enabled +# Purpose....: Check if DRYRUN mode is enabled +# --------------------------------------------------------------------------- +function dryrun_enabled () { + if [ "${TVDLDAP_DRYRUN^^}" == "TRUE" ]; then + return 0 + else + return 1 + fi +} + +# --------------------------------------------------------------------------- +# Function...: command_exists +# Purpose....: Check if a command does exists +# --------------------------------------------------------------------------- +function command_exists () { + command -v $1 >/dev/null 2>&1; +} + +# --------------------------------------------------------------------------- +# Function...: check_tools +# Purpose....: Check if the required tools are installed +# --------------------------------------------------------------------------- +function check_tools() { + TOOLS="$DEFAULT_TOOLS ${1:-""}" + echo_debug "DEBUG: List of tools to check: ${TOOLS}" + for i in ${TOOLS}; do + if ! command_exists ${i}; then + clean_quit 10 ${i} + exit 1 + fi + done +} + +# --------------------------------------------------------------------------- +# Function...: check_ldap_tools +# Purpose....: Check which LDAP tools are available +# --------------------------------------------------------------------------- +function check_ldap_tools() { + if [ $(ldapsearch -VV 2>&1 |grep -c "OpenLDAP" ) -ne 0 ]; then + export TVDLDAP_LDAPTOOLS="OPENLDAP" + echo_debug "DEBUG: Identified OpenLDAP Utilities. Set TVDLDAP_LDAPTOOLS=$TVDLDAP_LDAPTOOLS" + elif [ $(ldapsearch --version 2>&1 | grep -c "Oracle Unified") -ne 0 ]; then + export TVDLDAP_LDAPTOOLS="OUD" + echo_debug "DEBUG: Identified Oracle Unified Directory Utilities. Set TVDLDAP_LDAPTOOLS=$TVDLDAP_LDAPTOOLS" + else + export TVDLDAP_LDAPTOOLS="DB" + echo_debug "DEBUG: Assume Oracle Database LDAP Utilities. Set TVDLDAP_LDAPTOOLS=$TVDLDAP_LDAPTOOLS" + fi +} + +# --------------------------------------------------------------------------- +# Function...: check_openldap_tools +# Purpose....: Check if the required tools are OpenLDAP +# --------------------------------------------------------------------------- +function check_openldap_tools() { + TOOLS="ldapsearch ldapmodify ldapadd ldapdelete" + echo_debug "DEBUG: List of tools to check: ${TOOLS}" + for i in ${TOOLS}; do + if command_exists ${i}; then + if [ "$($i -VV 2>&1 |grep -c OpenLDAP)" -eq 0 ]; then + clean_quit 11 ${i} + fi + fi + done +} + +# --------------------------------------------------------------------------- +# Function...: ldapsearch_options +# Purpose....: Wrapper function to get ldapsearch options for the +# different ldapsearch implementations +# --------------------------------------------------------------------------- +function ldapsearch_options () { + if [ "${TVDLDAP_LDAPTOOLS^^}" == "OPENLDAP" ]; then + echo "-x -o ldif-wrap=no -LLL" + elif [ "${TVDLDAP_LDAPTOOLS^^}" == "OUD" ]; then + echo "-o 'ldif-wrap=no'" + elif [ "${TVDLDAP_LDAPTOOLS^^}" == "DB" ]; then + echo "-L" + else + echo "" + fi +} + +# --------------------------------------------------------------------------- +# Function...: ldapmodify_options +# Purpose....: Wrapper function to get ldapmodify options for the +# different ldapmodify implementations +# --------------------------------------------------------------------------- +function ldapmodify_options () { + if [ "${TVDLDAP_LDAPTOOLS^^}" == "OPENLDAP" ]; then + echo "" + elif [ "${TVDLDAP_LDAPTOOLS^^}" == "OUD" ]; then + echo "-a" + elif [ "${TVDLDAP_LDAPTOOLS^^}" == "DB" ]; then + echo "" + else + echo "" + fi +} + +# --------------------------------------------------------------------------- +# Function...: ldapadd_options +# Purpose....: Wrapper function to get ldapadd options for the +# different ldapadd implementations +# --------------------------------------------------------------------------- +function ldapadd_options () { + if [ "${TVDLDAP_LDAPTOOLS^^}" == "OPENLDAP" ]; then + echo "" + elif [ "${TVDLDAP_LDAPTOOLS^^}" == "OUD" ]; then + echo "-a" + elif [ "${TVDLDAP_LDAPTOOLS^^}" == "DB" ]; then + echo "" + else + echo "" + fi +} + +# --------------------------------------------------------------------------- +# Function...: ldapadd_command +# Purpose....: Wrapper function to get ldapadd command or map it to ldapmodify +# --------------------------------------------------------------------------- +function ldapadd_command () { + if ! command_exists ldapadd; then + echo "ldapmodify" + else + if [ "${TVDLDAP_LDAPTOOLS^^}" == "OUD" ]; then + echo "ldapmodify" + else + echo "ldapadd" + fi + fi +} + +# --------------------------------------------------------------------------- +# Function...: echo_debug +# Purpose....: Echo only if TVDLDAP_DEBUG variable is true +# --------------------------------------------------------------------------- +function echo_debug () { + if [ "${TVDLDAP_DEBUG^^}" == "TRUE" ]; then + echo $1 + fi +} + +# --------------------------------------------------------------------------- +# Function...: clean_quit +# Purpose....: Clean exit for all scripts +# --------------------------------------------------------------------------- +function clean_quit() { + + # define default values for function arguments + error=${1:-"0"} + error_value=${2:-""} + TVDLDAP_SCRIPT_NAME=${TVDLDAP_SCRIPT_NAME:-${LOCAL_SCRIPT_NAME}} + + case ${error} in + 0) echo "INFO : Successfully finish ${TVDLDAP_SCRIPT_NAME}";; + 1) echo "ERROR: Exit Code ${error}. Wrong amount of arguments. See usage for correct one." ;; + 2) echo "ERROR: Exit Code ${error}. Wrong arguments (${error_value}). See usage for correct one." >&2;; + 3) echo "ERROR: Exit Code ${error}. Missing mandatory argument (${error_value}). See usage ..." >&2;; + 4) echo "ERROR: Exit Code ${error}. Missing mandatory Bind arguments -D with -w, -W or -y. See usage ..." >&2;; + 5) echo "ERROR: Exit Code ${error}. Missing common function file (${error_value}) to source." >&2;; + 10) echo "ERROR: Exit Code ${error}. Command ${error_value} isn't installed/available on this system..." >&2;; + 11) echo "ERROR: Exit Code ${error}. LDAP tool ${error_value} in PATH is not OpenLDAP compatible..." >&2;; + 20) echo "ERROR: Exit Code ${error}. File ${error_value} already exists..." >&2;; + 21) echo "ERROR: Exit Code ${error}. Directory ${error_value} is not writeable..." >&2;; + 22) echo "ERROR: Exit Code ${error}. Can not read file ${error_value} ..." >&2;; + 23) echo "ERROR: Exit Code ${error}. Can not write file ${error_value} ..." >&2;; + 24) echo "ERROR: Exit Code ${error}. Can not create skip/reject files in ${error_value} ..." >&2;; + 25) echo "ERROR: Exit Code ${error}. Can not read file password file ${error_value} ..." >&2;; + 26) echo "ERROR: Exit Code ${error}. Can not write tempfile file ${error_value} ..." >&2;; + 30) echo "ERROR: Exit Code ${error}. Bind DN ${error_value} defined but no password parameter provided..." >&2;; + 31) echo "ERROR: Exit Code ${error}. Base DN ${error_value} does not exists..." >&2;; + 32) echo "ERROR: Exit Code ${error}. Base DN ALL not supported for ${error_value} ..." >&2;; + 33) echo "ERROR: Exit Code ${error}. Error running ${error_value} ..." >&2;; + *) echo "ERROR: Exit Code ${error}. But do not no realy why..." >&2;; + esac + + # remove tempfiles + if [ -f "$TEMPFILE" ]; then rm $TEMPFILE; fi + if [ -f "$TNSPING_TEMPFILE" ]; then rm $TNSPING_TEMPFILE; fi + + exit ${error} +} + +# --------------------------------------------------------------------------- +# Function...: load_config +# Purpose....: Load package specific configuration files +# --------------------------------------------------------------------------- +function load_config() { + echo_debug "DEBUG: Start to source configuration files" + for config in ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}.conf \ + ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}_custom.conf \ + ${ETC_BASE}/${TOOL_BASE_NAME}.conf \ + ${ETC_BASE}/${TOOL_BASE_NAME}_custom.conf; do + if [ -f "${config}" ]; then + echo_debug "DEBUG: source configuration file ${config}" + . ${config} + export TVDLDAP_CONFIG_FILES="$TVDLDAP_CONFIG_FILES${config} " + fi + done +} + +# --------------------------------------------------------------------------- +# Function...: dump_runtime_config +# Purpose....: Dump / display runtime configuration and variables +# --------------------------------------------------------------------------- +function dump_runtime_config() { + echo_debug "DEBUG: Dump current ${TOOL_BASE_NAME} specific environment variables" + if [ "${TVDLDAP_DEBUG^^}" == "TRUE" ]; then + for i in $(env|grep -i "${TOOL_BASE_NAME}_"|sort); do + variable=$(echo "$i"|cut -d= -f1) + value=$(echo "$i"|cut -d= -f2) + value=${value:-"undef"} + printf "DEBUG: %s%s %s\n" "${variable}" "${padding:${#variable}}" "${value}" + done + fi +} + +# --------------------------------------------------------------------------- +# Function...: rotate_logfiles +# Purpose....: Rotate and purge log files +# --------------------------------------------------------------------------- +function rotate_logfiles() { + TVDLDAP_KEEP_LOG_DAYS=${1:-$TVDLDAP_KEEP_LOG_DAYS} + echo_debug "DEBUG: purge files older for ${TVDLDAP_SCRIPT_NAME} than $TVDLDAP_KEEP_LOG_DAYS" + find $LOG_BASE -name "$(basename ${TVDLDAP_SCRIPT_NAME} .sh)*.log" \ + -mtime +${TVDLDAP_KEEP_LOG_DAYS} -exec rm {} \; +} + +# --------------------------------------------------------------------------- +# Function...: get_all_basedn +# Purpose....: get base dn from LDAP server namingContexts +# --------------------------------------------------------------------------- +function get_all_basedn() { + TVDLDAP_LDAPHOST=${1:-$(get_ldaphost)} + TVDLDAP_LDAPPORT=${2:-$(get_ldapport)} + ldapsearch_options=$(ldapsearch_options) + ldapsearch -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} -b "" \ + ${ldapsearch_options} -s base "(objectClass=*)" \ + namingContexts| grep -i namingContexts| sed 's/namingContexts=//g' | cut -d: -f2| xargs + if [ $? -ne 0 ]; then + clean_quit 33 "ldapsearch" + fi +} + +# --------------------------------------------------------------------------- +# Function...: get_local_basedn +# Purpose....: get base dn from ldap.ora DEFAULT_ADMIN_CONTEXT +# --------------------------------------------------------------------------- +function get_local_basedn() { + if [ -f "$TNS_ADMIN/ldap.ora" ]; then + grep -i "^DEFAULT_ADMIN_CONTEXT" $TNS_ADMIN/ldap.ora|sed 's/.*"\(.*\)".*/\1/' + else + echo $TVDLDAP_BASEDN + fi +} + +# --------------------------------------------------------------------------- +# Function...: get_basedn +# Purpose....: get base correct base DN. Either default, ldap.ora or all, check +# if user provided base DN are valid +# --------------------------------------------------------------------------- +function get_basedn() { + TVDLDAP_BASEDN="${1}" + LOCAL_BASEDN="" + # get base DN information + if [ -z "$TVDLDAP_BASEDN" ]; then + LOCAL_BASEDN=$(get_local_basedn) + elif [ "${TVDLDAP_BASEDN^^}" == "ALL" ]; then + LOCAL_BASEDN=$(get_all_basedn) + else + if [[ "$TVDLDAP_BASEDN" =~ ^dc=.* ]]; then + LOCAL_BASEDN=$TVDLDAP_BASEDN + else + LOCAL_BASEDN=$(echo $TVDLDAP_BASEDN|sed -e 's/\./,dc=/g' -e 's/^/dc=/') + fi + if [[ "$(get_all_basedn)" != *"${LOCAL_BASEDN}"* ]]; then + clean_quit 31 ${LOCAL_BASEDN} + fi + fi + echo $LOCAL_BASEDN +} + +# --------------------------------------------------------------------------- +# Function...: basedn_exists +# Purpose....: check if base does exists in ldap.ora namingContexts +# --------------------------------------------------------------------------- +function basedn_exists() { + my_basedn=${1:-""} + ALL_BASEDN=$(get_all_basedn) # get list of all base DN + + if [[ "$my_basedn" =~ ^dc=.* ]]; then + my_basedn=$my_basedn # keep base DN as it is + else + # convert regular domain name into a base DN + my_basedn=$(echo $my_basedn|sed -e 's/\./,dc=/g' -e 's/^/dc=/') + fi + # check if my_basedn is in the list of all base DN + if [[ "${ALL_BASEDN}" == *"${my_basedn}"* ]]; then + return 0 + else + return 1 + fi +} + +# --------------------------------------------------------------------------- +# Function...: split_net_service_basedn +# Purpose....: split base DN from full qualified Net Service Name +# --------------------------------------------------------------------------- +function split_net_service_basedn() { + my_netservice=${1:-""} + if [ -n "${my_netservice}" ]; then + if [[ "${my_netservice}" == *"."* ]]; then + echo $my_netservice| cut -d. -f2-| tr '[:upper:]' '[:lower:]'|sed -e 's/\./,dc=/g' -e 's/^/dc=/' + else + echo "" + fi + else + echo "" + fi +} + +# --------------------------------------------------------------------------- +# Function...: split_net_service_cn +# Purpose....: split Net Service Name from full qualified Net Service Name +# --------------------------------------------------------------------------- +function split_net_service_cn() { + my_netservice=${1:-""} + if [ -n "${my_netservice}" ]; then + if [[ "${my_netservice}" == *"."* ]]; then + echo $my_netservice| cut -d. -f1 + else + echo $my_netservice + fi + else + echo "" + fi +} + +# --------------------------------------------------------------------------- +# Function...: net_service_exists +# Purpose....: check if Net Service Name does exists +# --------------------------------------------------------------------------- +function net_service_exists() { + my_netservice=${1:-""} + my_basedn=${2:-"$(get_local_basedn)"} # get the default Base DN from ldap.ora + my_ldaphost=$(get_ldaphost) # get ldap host from ldap.ora + my_ldapport=$(get_ldapport) # get ldap port from ldap.ora + current_cn=$(split_net_service_cn ${my_netservice}) # get pure Net Service Name + current_basedn=$(split_net_service_basedn ${my_netservice}) # get Base DN from Net Service Name + current_basedn=${current_basedn:-$my_basedn} # set the Base DN if not defined in Net Service Name + + ldapsearch_options=$(ldapsearch_options) + if [ -n "${current_cn}" ]; then + result=$(ldapsearch -h ${my_ldaphost} -p ${my_ldapport} -b $current_basedn $ldapsearch_options -s sub "(&(cn=${current_cn})(|(objectClasses=orclNetService)(objectClass=orclService)(objectClass=orclNetServiceAlias)))" dn) + if [ $? -ne 0 ]; then + clean_quit 33 "ldapsearch" + fi + if [ -z "$result" ]; then + return 1 + else + return 0 + fi + fi +} + +# --------------------------------------------------------------------------- +# Function...: check_bind_parameter +# Purpose....: check the correct bind parameter and combination +# --------------------------------------------------------------------------- +function check_bind_parameter() { + TVDLDAP_BINDDN="${1}" + TVDLDAP_BINDDN_PWD="${2}" + TVDLDAP_BINDDN_PWDFILE="${3}" + TVDLDAP_BINDDN_PWDASK="${4}" + if [ -n "$TVDLDAP_BINDDN" ] && [ -n "$TVDLDAP_BINDDN_PWDFILE" ] ; then + if [ ! -f "$TVDLDAP_BINDDN_PWDFILE" ]; then + clean_quit 22 $TVDLDAP_BINDDN_PWDFILE + fi + elif [ -n "$TVDLDAP_BINDDN" ] && [ "${TVDLDAP_BINDDN_PWDASK^^}" == "TRUE" ] ; then + BIND_PARA=("-D '$TVDLDAP_BINDDN'" "-W") + elif [ -n "$TVDLDAP_BINDDN" ] && [ -n "$TVDLDAP_BINDDN_PWD" ] ; then + BIND_PARA=("-D '$TVDLDAP_BINDDN'" "-w $TVDLDAP_BINDDN_PWD") + elif [ -n "$TVDLDAP_BINDDN" ] ; then + clean_quit 30 "$TVDLDAP_BINDDN" + else + BIND_PARA=() + fi + echo "${BIND_PARA[@]}" +} + +# --------------------------------------------------------------------------- +# Function...: get_binddn_param +# Purpose....: create Bind DN Parameter +# --------------------------------------------------------------------------- +function get_binddn_param() { + my_binddn=${1:-$TVDLDAP_BINDDN} + if [ -n "$my_binddn" ]; then + echo "-D $my_binddn" + else + echo "" + fi +} + +# --------------------------------------------------------------------------- +# Function...: ask_bindpwd +# Purpose....: Ask for the Bind password if not supported by the LDAP utilities +# --------------------------------------------------------------------------- +function ask_bindpwd() { + if [ -n "$TVDLDAP_BINDDN_PWDASK" ] && [ -n "$TVDLDAP_BINDDN_PWD" ]; then + if [ "${TVDLDAP_BINDDN_PWDASK^^}" == "TRUE" ] && [ "${TVDLDAP_LDAPTOOLS^^}" == "OPENLDAP" ]; then + export TVDLDAP_BINDDN_PWDASK=$TVDLDAP_BINDDN_PWDASK + else + echo -n Password: + read -s password + echo + export TVDLDAP_BINDDN_PWD="$password" + export TVDLDAP_BINDDN_PWDASK="FALSE" + fi + fi +} + +# --------------------------------------------------------------------------- +# Function...: get_bindpwd_param +# Purpose....: create Bind password parameter +# --------------------------------------------------------------------------- +function get_bindpwd_param() { + my_bindpwd=${1:-$TVDLDAP_BINDDN_PWD} + my_bindpwd_ask=${2:-$TVDLDAP_BINDDN_PWDASK} + my_bindpwd_file=${3:-$TVDLDAP_BINDDN_PWDFILE} + if [ -n "$my_bindpwd" ]; then + echo "-w $my_bindpwd" + elif [ "${my_bindpwd_ask^^}" == "TRUE" ]; then + echo "-W" + elif [ -n "$my_bindpwd_file" ]; then + # check if bind password file does exists + if [ -f "$my_bindpwd_file" ]; then + # set the bind password parameter for OpenLDAP + if [ "${TVDLDAP_LDAPTOOLS^^}" == "OPENLDAP" ]; then + echo "-y $my_bindpwd_file" + # set the bind password parameter for OUD + elif [ "${TVDLDAP_LDAPTOOLS^^}" == "OUD" ]; then + echo "-j $my_bindpwd_file" + # set the bind password for anything else + else + echo "-w $(cat $my_bindpwd_file)" + fi + else + # quit if the password file is not accessible + clean_quit 25 $my_bindpwd_file + fi + else + echo "" + fi +} + +# --------------------------------------------------------------------------- +# Function...: get_ldaphost +# Purpose....: get ldap host from ldap.ora +# --------------------------------------------------------------------------- +function get_ldaphost() { + if [ -f "$TNS_ADMIN/ldap.ora" ]; then + grep -i "^DIRECTORY_SERVERS" $TNS_ADMIN/ldap.ora|sed 's/.*(\([^]]*\)).*/\1/g'|cut -d, -f1| cut -d: -f1 + else + echo ${TVDLDAP_LDAPHOST:-$TVDLDAP_DEFAULT_LDAPHOST} + fi +} + +# --------------------------------------------------------------------------- +# Function...: get_ldapport +# Purpose....: get ldap port from ldap.ora +# --------------------------------------------------------------------------- +function get_ldapport() { + if [ -f "$TNS_ADMIN/ldap.ora" ]; then + grep -i "^DIRECTORY_SERVERS" $TNS_ADMIN/ldap.ora|sed 's/.*(\([^]]*\)).*/\1/g'|cut -d, -f1| cut -d: -f2 + else + echo ${TVDLDAP_LDAPPORT:-$TVDLDAP_DEFAULT_LDAPPORT} + fi +} + +# - EOF Functions ----------------------------------------------------------- + +# - Initialization ---------------------------------------------------------- + +# - EOF Initialization ------------------------------------------------------- + +# - Main --------------------------------------------------------------------- +# check if script is sourced and return/exit +if [ "${BASH_SOURCE[0]}" != "${0}" ]; then + echo_debug "DEBUG: Script ${BASH_SOURCE[0]} is sourced from ${0}" +else + echo "INFO : Script ${BASH_SOURCE[0]} is executed directly. No action is performed." + clean_quit +fi +# --- EOF -------------------------------------------------------------------- \ No newline at end of file diff --git a/bin/tns_load.sh b/bin/tns_load.sh new file mode 100755 index 0000000..8d92f0a --- /dev/null +++ b/bin/tns_load.sh @@ -0,0 +1,280 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tns_load.sh +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: Load a tnsnames.ora +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# - Customization ------------------------------------------------------------ +# - just add/update any kind of customized environment variable here +DEFAULT_OUTPUT_DIR=$TNS_ADMIN +DEFAULT_FILE_PREFIX="ldap_dump" +# - End of Customization ---------------------------------------------------- + +# Define a bunch of bash option see +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o nounset # exit if script try to use an uninitialised variable +set -o errexit # exit script if any statement returns a non-true return value +set -o pipefail # pipefail exit after 1st piped commands failed + +# - Environment Variables --------------------------------------------------- +# define generic environment variables +VERSION=v0.1.0 +TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE:-"FALSE"} # enable verbose mode +TVDLDAP_DEBUG=${TVDLDAP_DEBUG:-"FALSE"} # enable debug mode +TVDLDAP_QUIET=${TVDLDAP_QUIET:-"FALSE"} # enable quiet mode +TVDLDAP_SCRIPT_NAME=$(basename ${BASH_SOURCE[0]}) +TVDLDAP_BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +TVDLDAP_LOG_DIR="$(dirname ${TVDLDAP_BIN_DIR})/log" + +# define logfile and logging +LOG_BASE=${LOG_BASE:-"${TVDLDAP_LOG_DIR}"} # Use script log directory as default logbase +TIMESTAMP=$(date "+%Y.%m.%d_%H%M%S") +readonly LOGFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$TIMESTAMP.log" +# - EOF Environment Variables ----------------------------------------------- + +# - Functions --------------------------------------------------------------- +# --------------------------------------------------------------------------- +# Function...: Usage +# Purpose....: Display Usage and exit script +# --------------------------------------------------------------------------- +function Usage() { + + # define default values for function arguments + error=${1:-"0"} # default error number + error_value=${2:-""} # default error message + cat << EOI + + Usage: ${TVDLDAP_SCRIPT_NAME} [options] [bind options] [load options] + + Common Options: + -m Usage this message + -v Enable verbose mode (default \$TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE}) + -d Enable debug mode (default \$TVDLDAP_DEBUG=${TVDLDAP_DEBUG}) + -b Specify Base DN to search Net Service Name. Either + specific base DN or ALL to search Net Service Name in + all available namingContexts. By the default the Base + DN is derived from a fully qualified Net Service Name. + Otherwise the default Base DN is taken from ldap.ora. Can + also be specified by setting TVDLDAP_BASEDN. + -h LDAP server (default take from ldap.ora). Can be specified + by setting TVDLDAP_LDAPHOST. + -p port on LDAP server (default take from ldap.ora). Can be + specified by setting TVDLDAP_LDAPPORT. + + Bind Options: + -D Bind DN (default ANONYMOUS). Can be specified by setting + TVDLDAP_BINDDN. + -w Bind password. Can be specified by setting TVDLDAP_BINDDN_PWD. + -W prompt for bind password. Can be specified by setting + TVDLDAP_BINDDN_PWDASK. + -y Read password from file. Can be specified by setting + TVDLDAP_BINDDN_PWDFILE. + + Load options: + -t tnsnames.ora file to read and load (mandatory) + -n Show what would be done but do not actually do it + -F Force mode to add entry it it does not exists + + Configuration file: + The script does load configuration files to define default values as an + alternative for command line parameter. e.g. to set a bind DN TVDLDAP_BINDDN + LDAP hostname TVDLDAP_LDAPHOST, etc. The configuration files are loaded in + the following order: + + 1. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}.conf + 2. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}_custom.conf + 3. ${ETC_BASE}/${TOOL_BASE_NAME}.conf + 4. ${ETC_BASE}/${TOOL_BASE_NAME}_custom.conf + 5. Command line parameter + + Logfile : ${LOGFILE} + +EOI + dump_runtime_config # dump current tool specific environment in debug mode + clean_quit ${error} ${error_value} +} +# - EOF Functions ----------------------------------------------------------- + +# - Initialization ---------------------------------------------------------- +# initialize logfile +touch $LOGFILE 2>/dev/null +exec &> >(tee -a "$LOGFILE") # Open standard out at `$LOG_FILE` for write. +exec 2>&1 +echo "INFO : Start ${TVDLDAP_SCRIPT_NAME} on host $(hostname) at $(date)" + +# source common variables and functions from tns_functions.sh +if [ -f ${TVDLDAP_BIN_DIR}/tns_functions.sh ]; then + . ${TVDLDAP_BIN_DIR}/tns_functions.sh +else + echo "ERROR: Can not find common functions ${TVDLDAP_BIN_DIR}/tns_functions.sh" + exit 5 +fi + +load_config # load configuration files. File list in TVDLDAP_CONFIG_FILES + +# get options +while getopts mvdb:h:p:D:w:Wy:t:FnE: CurOpt; do + case ${CurOpt} in + m) Usage 0;; + v) TVDLDAP_VERBOSE="TRUE" ;; + d) TVDLDAP_DEBUG="TRUE" ;; + b) TVDLDAP_BASEDN="${OPTARG}";; + h) TVDLDAP_LDAPHOST=${OPTARG};; + p) TVDLDAP_LDAPPORT=${OPTARG};; + D) TVDLDAP_BINDDN="${OPTARG}";; + w) TVDLDAP_BINDDN_PWD="${OPTARG}";; + W) TVDLDAP_BINDDN_PWDASK="TRUE";; + y) TVDLDAP_BINDDN_PWDFILE="${OPTARG}";; + t) TNSNAMES_FILES="${OPTARG}";; + F) TVDLDAP_FORCE="TRUE";; + n) TVDLDAP_DRYRUN="TRUE";; + E) clean_quit "${OPTARG}";; + *) Usage 2 $*;; + esac +done + +check_tools # check if we do have the required LDAP tools available +check_ldap_tools # check what kind of LDAP tools we do have e.g. + # OpenLDAP, Oracle DB or Oracle Unified Directory +dump_runtime_config # dump current tool specific environment in debug mode + +# get the ldapmodify and ldapadd options based on available tools +ldapmodify_options=$(ldapmodify_options) + +# check if the current LDAP utilites does provide an +if ! command_exists ldapadd; then + ldapadd_command="ldapmodify" + ldapadd_options=$(ldapmodify_options) +else + ldapadd_command="ldapadd" + ldapadd_options=$(ldapadd_options) +fi + +# Default values +TNSNAMES_FILES=${TNSNAMES_FILES:-""} +if [ -z "${TNSNAMES_FILES}" ]; then clean_quit 3 "-t"; fi + +# get default values for LDAP Server +TVDLDAP_LDAPHOST=${TVDLDAP_LDAPHOST:-$(get_ldaphost)} +TVDLDAP_LDAPPORT=${TVDLDAP_LDAPPORT:-$(get_ldapport)} + +# get bind parameter +ask_bindpwd # ask for the bind password if TVDLDAP_BINDDN_PWDASK + # is TRUE and LDAP tools are not OpenLDAP +current_binddn=$(get_binddn_param "$TVDLDAP_BINDDN" ) +current_bindpwd=$(get_bindpwd_param "$TVDLDAP_BINDDN_PWD" ${TVDLDAP_BINDDN_PWDASK} "$TVDLDAP_BINDDN_PWDFILE") +if [ -z "$current_binddn" ] && [ -z "${current_bindpwd}" ]; then clean_quit 4; fi + +# get base DN information if not ALL specified +if [ "${TVDLDAP_BASEDN^^}" == "ALL" ]; then clean_quit 32 ${TVDLDAP_SCRIPT_NAME} ;fi +common_basedn=$(get_basedn "$TVDLDAP_BASEDN") + +# - EOF Initialization ------------------------------------------------------- + +# - Main --------------------------------------------------------------------- +echo_debug "DEBUG: Configuration / Variables:" +echo_debug "DEBUG: LDAP Host............... = $TVDLDAP_LDAPHOST" +echo_debug "DEBUG: LDAP Port............... = $TVDLDAP_LDAPPORT" +echo_debug "DEBUG: Bind DN................. = $TVDLDAP_BINDDN" +echo_debug "DEBUG: Bind PWD................ = $TVDLDAP_BINDDN_PWD" +echo_debug "DEBUG: Bind PWD File........... = $TVDLDAP_BINDDN_PWDFILE" +echo_debug "DEBUG: Bind parameter.......... = $current_binddn $current_bindpwd" +echo_debug "DEBUG: Common Base DN.......... = $common_basedn" +echo_debug "DEBUG: tnsnames file........... = $TNSNAMES_FILES" +echo_debug "DEBUG: ldapmodify options...... = $ldapmodify_options" +echo_debug "DEBUG: ldapadd options......... = $ldapadd_options" + +for file in $TNSNAMES_FILES; do + echo_debug "DEBUG: Start to process file $file" + # check if we can access the file + if [ ! -f "${file}" ]; then clean_quit 22 "${file}"; fi + + # check if we can write to the folder to create the skip / reject files + if [ ! -w "$(dirname ${file})" ]; then clean_quit 24 "$(dirname ${file})"; fi + + # start to read the file + while IFS= read -r line ; do + net_service=$(echo $line| cut -d'=' -f1) + current_cn=$(split_net_service_cn ${net_service}) # get pure Net Service Name + current_basedn=$(split_net_service_basedn ${net_service}) + current_basedn=${current_basedn:-"${common_basedn}"} + NetDescString=$(echo $line| cut -d'=' -f2-) + # check for , in service name => reject + if [[ "${net_service}" == *","* ]]; then + echo "WARN : Can not handle comma in Net Service Name, reject Net Service Name ${net_service}" + echo "# Can not handle comma in Net Service Name ${net_service}" >>"${file}_reject" || clean_quit 23 ${file}_reject + echo "${net_service}=${NetDescString}" >>"${file}_reject" + continue + fi + + # check if base DN exists => reject + if ! basedn_exists ${current_basedn}; then + echo "WARN : Base DN ${current_basedn} does not exists, reject Net Service Name ${net_service}" + echo "# Base DN ${current_basedn} does not exists, reject Net Service Name ${net_service}" >>"${file}_reject" + echo "${net_service}=${NetDescString}" >>"${file}_reject" + continue + fi + echo_debug "DEBUG: Net Service Name => $net_service" + echo_debug "DEBUG: cn => $current_cn" + echo_debug "DEBUG: basedn => $current_basedn" + echo_debug "DEBUG: NetDescString => $NetDescString" + # check if net service entry exists => skip if force = FALSE + if ! net_service_exists "$current_cn" "${current_basedn}" ; then + echo "INFO : Add Net Service Name $net_service in $current_basedn" + if ! dryrun_enabled; then + $ldapadd_command -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapadd_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$current_basedn +objectclass: top +objectclass: orclNetService +cn: $current_cn +orclNetDescString: $NetDescString + +EOI + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "$ldapadd_command"; fi + else + echo "INFO : Dry run enabled, skip add Net Service Name $current_cn in $current_basedn" + fi + else + if force_enabled; then + echo "INFO : Modify Net Service Name $net_service in $current_basedn" + if ! dryrun_enabled; then + ldapmodify -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapmodify_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$current_basedn +changetype: modify +replace: orclNetDescString +orclNetDescString: $NetDescString + +EOI + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "ldapmodify"; fi + else + echo "INFO : Dry run enabled, skip modify Net Service Name $current_cn in $current_basedn" + fi + else + echo "WARN : Net Service Name does exists in $current_basedn, skip ${net_service}" + echo "# Net Service Name does exists in $current_basedn, skip ${net_service}" >>"${file}_skip" + echo "${net_service}=${NetDescString}" >>"${file}_skip" + fi + fi + done < <(cat ${file}|sed -e 's/^#\s*$/DELIM/g' -e 's/^\s*$/DELIM/g'|grep -v '^#'| sed -e 's/\s*//g' -e '/^[a-zA-Z0-9.]*=/s/^/DELIM\n/'|tr -d '\n'| sed -e 's/DELIM/\n/g' -e 's/$/\n/' |sed '/^$/d') +done + +rotate_logfiles # purge log files based on TVDLDAP_KEEP_LOG_DAYS +clean_quit # clean exit with return code 0 +# --- EOF -------------------------------------------------------------------- diff --git a/bin/tns_modify.sh b/bin/tns_modify.sh new file mode 100755 index 0000000..0e740a4 --- /dev/null +++ b/bin/tns_modify.sh @@ -0,0 +1,288 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tns_modify.sh +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: Modify a tns entry +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# - Customization ------------------------------------------------------------ +# - just add/update any kind of customized environment variable here + +# - End of Customization ---------------------------------------------------- + +# Define a bunch of bash option see +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o nounset # exit if script try to use an uninitialised variable +set -o errexit # exit script if any statement returns a non-true return value +set -o pipefail # pipefail exit after 1st piped commands failed + +# - Environment Variables --------------------------------------------------- +# define generic environment variables +VERSION=v0.1.0 +TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE:-"FALSE"} # enable verbose mode +TVDLDAP_DEBUG=${TVDLDAP_DEBUG:-"FALSE"} # enable debug mode +TVDLDAP_QUIET=${TVDLDAP_QUIET:-"FALSE"} # enable quiet mode +TVDLDAP_SCRIPT_NAME=$(basename ${BASH_SOURCE[0]}) +TVDLDAP_BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +TVDLDAP_LOG_DIR="$(dirname ${TVDLDAP_BIN_DIR})/log" + +# define logfile and logging +LOG_BASE=${LOG_BASE:-"${TVDLDAP_LOG_DIR}"} # Use script log directory as default logbase +TIMESTAMP=$(date "+%Y.%m.%d_%H%M%S") +readonly LOGFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$TIMESTAMP.log" +# - EOF Environment Variables ----------------------------------------------- + +# - Functions --------------------------------------------------------------- +# --------------------------------------------------------------------------- +# Function...: Usage +# Purpose....: Display Usage and exit script +# --------------------------------------------------------------------------- +function Usage() { + + # define default values for function arguments + error=${1:-"0"} # default error number + error_value=${2:-""} # default error message + cat << EOI + + Usage: ${TVDLDAP_SCRIPT_NAME} [options] [bind options] [modify options] + + Common Options: + -m Usage this message + -v Enable verbose mode (default \$TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE}) + -d Enable debug mode (default \$TVDLDAP_DEBUG=${TVDLDAP_DEBUG}) + -b Specify Base DN to search Net Service Name. Either + specific base DN or ALL to search Net Service Name in + all available namingContexts. By the default the Base + DN is derived from a fully qualified Net Service Name. + Otherwise the default Base DN is taken from ldap.ora. Can + also be specified by setting TVDLDAP_BASEDN. + -h LDAP server (default take from ldap.ora). Can be specified + by setting TVDLDAP_LDAPHOST. + -p port on LDAP server (default take from ldap.ora). Can be + specified by setting TVDLDAP_LDAPPORT. + + Bind Options: + -D Bind DN (default ANONYMOUS). Can be specified by setting + TVDLDAP_BINDDN. + -w Bind password. Can be specified by setting TVDLDAP_BINDDN_PWD. + -W prompt for bind password. Can be specified by setting + TVDLDAP_BINDDN_PWDASK. + -y Read password from file. Can be specified by setting + TVDLDAP_BINDDN_PWDFILE. + + Modify options: + -S Oracle Net Service Name to modify (mandatory) + -N Oracle Net Service description string (mandatory) + -A Modify an Oracle Net Service alias rather a full description + string. If this option is specified -N must just be a target + Oracle Net Service Name for the alias + -n Show what would be done but do not actually do it + -F Force mode to add entry it it does not exists + + Configuration file: + The script does load configuration files to define default values as an + alternative for command line parameter. e.g. to set a bind DN TVDLDAP_BINDDN + LDAP hostname TVDLDAP_LDAPHOST, etc. The configuration files are loaded in + the following order: + + 1. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}.conf + 2. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}_custom.conf + 3. ${ETC_BASE}/${TOOL_BASE_NAME}.conf + 4. ${ETC_BASE}/${TOOL_BASE_NAME}_custom.conf + 5. Command line parameter + + Logfile : ${LOGFILE} + +EOI + dump_runtime_config # dump current tool specific environment in debug mode + clean_quit ${error} ${error_value} +} +# - EOF Functions ----------------------------------------------------------- + +# - Initialization ---------------------------------------------------------- +# initialize logfile +touch $LOGFILE 2>/dev/null +exec &> >(tee -a "$LOGFILE") # Open standard out at `$LOG_FILE` for write. +exec 2>&1 +echo "INFO : Start ${TVDLDAP_SCRIPT_NAME} on host $(hostname) at $(date)" + +# source common variables and functions from tns_functions.sh +if [ -f ${TVDLDAP_BIN_DIR}/tns_functions.sh ]; then + . ${TVDLDAP_BIN_DIR}/tns_functions.sh +else + echo "ERROR: Can not find common functions ${TVDLDAP_BIN_DIR}/tns_functions.sh" + exit 5 +fi + +load_config # load configuration files. File list in TVDLDAP_CONFIG_FILES + +# get options +while getopts mvdb:h:p:D:w:Wy:S:N:nFAE: CurOpt; do + case ${CurOpt} in + m) Usage 0;; + v) TVDLDAP_VERBOSE="TRUE" ;; + d) TVDLDAP_DEBUG="TRUE" ;; + b) TVDLDAP_BASEDN="${OPTARG}";; + h) TVDLDAP_LDAPHOST=${OPTARG};; + p) TVDLDAP_LDAPPORT=${OPTARG};; + D) TVDLDAP_BINDDN="${OPTARG}";; + w) TVDLDAP_BINDDN_PWD="${OPTARG}";; + W) TVDLDAP_BINDDN_PWDASK="TRUE";; + y) TVDLDAP_BINDDN_PWDFILE="${OPTARG}";; + F) TVDLDAP_FORCE="TRUE";; + n) TVDLDAP_DRYRUN="TRUE";; + A) TVDLDAP_NETALIAS="TRUE";; + S) NETSERVICE=${OPTARG};; + N) NETDESCSTRING="${OPTARG}";; + E) clean_quit "${OPTARG}";; + *) Usage 2 $*;; + esac +done + +# display usage and exit if parameter is null +if [ $# -eq 0 ]; then + Usage 1 +fi + +check_tools # check if we do have the required LDAP tools available +check_ldap_tools # check what kind of LDAP tools we do have e.g. + # OpenLDAP, Oracle DB or Oracle Unified Directory +dump_runtime_config # dump current tool specific environment in debug mode + +# get the ldapmodify and ldapadd options based on available tools +ldapmodify_options=$(ldapmodify_options) +ldapadd_command=$(ldapadd_command) +ldapadd_options=$(ldapadd_options) + +# Default values +export NETSERVICE=${NETSERVICE:-""} +export NETDESCSTRING=${NETDESCSTRING:-""} + +# check for mandatory parameters +if [ -z "${NETSERVICE}" ]; then clean_quit 3 "-S"; fi +if [ -z "${NETDESCSTRING}" ]; then clean_quit 3 "-N"; fi + +# get default values for LDAP Server +TVDLDAP_LDAPHOST=${TVDLDAP_LDAPHOST:-$(get_ldaphost)} +TVDLDAP_LDAPPORT=${TVDLDAP_LDAPPORT:-$(get_ldapport)} + +# get bind parameter +ask_bindpwd # ask for the bind password if TVDLDAP_BINDDN_PWDASK + # is TRUE and LDAP tools are not OpenLDAP +current_binddn=$(get_binddn_param "$TVDLDAP_BINDDN" ) +current_bindpwd=$(get_bindpwd_param "$TVDLDAP_BINDDN_PWD" ${TVDLDAP_BINDDN_PWDASK} "$TVDLDAP_BINDDN_PWDFILE") +if [ -z "$current_binddn" ] && [ -z "${current_bindpwd}" ]; then clean_quit 4; fi + +# get base DN information +BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") + +# Split Net Service Name if full qualified e.g. with a dot +current_basedn=$(split_net_service_basedn ${NETSERVICE}) +current_cn=$(split_net_service_cn ${NETSERVICE}) +# - EOF Initialization ------------------------------------------------------- + +# - Main --------------------------------------------------------------------- +echo_debug "DEBUG: Configuration / Variables:" +echo_debug "DEBUG: LDAP Host............... = $TVDLDAP_LDAPHOST" +echo_debug "DEBUG: LDAP Port............... = $TVDLDAP_LDAPPORT" +echo_debug "DEBUG: Bind DN................. = $TVDLDAP_BINDDN" +echo_debug "DEBUG: Bind PWD................ = $TVDLDAP_BINDDN_PWD" +echo_debug "DEBUG: Bind PWD File........... = $TVDLDAP_BINDDN_PWDFILE" +echo_debug "DEBUG: Bind parameter.......... = $current_binddn $current_bindpwd" +echo_debug "DEBUG: Base DN................. = $BASEDN_LIST" +echo_debug "DEBUG: Net Service Names....... = $NETSERVICE" +echo_debug "DEBUG: Net Service Name CN..... = $current_cn" +echo_debug "DEBUG: Net Service Name Base DN = $current_basedn" +echo_debug "DEBUG: Net Service Description. = $NETDESCSTRING" +echo_debug "DEBUG: Net Service Alias....... = $TVDLDAP_NETALIAS" +echo_debug "DEBUG: ldapmodify options...... = $ldapmodify_options" +echo_debug "DEBUG: ldapadd options......... = $ldapadd_options" + +# Set BASEDN_LIST to current Base DN from Net Service Name +if [ -n "${current_basedn}" ]; then BASEDN_LIST=${current_basedn}; fi + +# loop over base DN +for basedn in ${BASEDN_LIST}; do + echo_debug "DEBUG: Process base dn $basedn" + if ! net_service_exists "$current_cn" "${basedn}" ; then + if force_enabled; then + echo "INFO : Add Net Service Name $current_cn in $basedn" + if ! dryrun_enabled; then + if ! alias_enabled; then + $ldapadd_command -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapadd_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$basedn +objectclass: top +objectclass: orclNetService +cn: $current_cn +orclNetDescString: $NETDESCSTRING + +EOI + else + aliasedObjectName=$(split_net_service_cn ${NETDESCSTRING}) + $ldapadd_command -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapadd_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$basedn +aliasedObjectName: cn=$aliasedObjectName,cn=OracleContext,$basedn +objectClass: alias +objectClass: top +objectClass: orclNetServiceAlias +cn: $current_cn + +EOI + fi + + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "$ldapadd_command"; fi + else + echo "INFO : Dry run enabled, skip add Net Service Name $current_cn in $basedn" + fi + else + echo "WARN : Net Service Name $current_cn does not exists in $current_basedn. Enable force mode to add it." + fi + else + echo "INFO : Modify Net Service Name $current_cn in $current_basedn" + if ! dryrun_enabled; then + if ! alias_enabled; then + ldapmodify -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapmodify_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$current_basedn +changetype: modify +replace: orclNetDescString +orclNetDescString: $NETDESCSTRING + +EOI + else + aliasedObjectName=$(split_net_service_cn ${NETDESCSTRING}) + ldapmodify -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} \ + ${current_bindpwd} ${ldapmodify_options} <<-EOI +dn: cn=$current_cn,cn=OracleContext,$current_basedn +changetype: modify +replace: aliasedObjectName +aliasedObjectName: cn=$aliasedObjectName,cn=OracleContext,$basedn + +EOI + fi + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "ldapmodify"; fi + fi + fi +done + +rotate_logfiles # purge log files based on TVDLDAP_KEEP_LOG_DAYS +clean_quit # clean exit with return code 0 +# --- EOF -------------------------------------------------------------------- diff --git a/bin/tns_search.sh b/bin/tns_search.sh new file mode 100755 index 0000000..1312aa0 --- /dev/null +++ b/bin/tns_search.sh @@ -0,0 +1,262 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tns_search.sh +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: Search a tns entry +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# - Customization ------------------------------------------------------------ +# - just add/update any kind of customized environment variable here + +# - End of Customization ---------------------------------------------------- + +# Define a bunch of bash option see +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o nounset # exit if script try to use an uninitialised variable +set -o errexit # exit script if any statement returns a non-true return value +set -o pipefail # pipefail exit after 1st piped commands failed + +# - Environment Variables --------------------------------------------------- +# define generic environment variables +VERSION=v0.1.0 +TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE:-"FALSE"} # enable verbose mode +TVDLDAP_DEBUG=${TVDLDAP_DEBUG:-"FALSE"} # enable debug mode +TVDLDAP_QUIET=${TVDLDAP_QUIET:-"FALSE"} # enable quiet mode +TVDLDAP_SCRIPT_NAME=$(basename ${BASH_SOURCE[0]}) +TVDLDAP_BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +TVDLDAP_LOG_DIR="$(dirname ${TVDLDAP_BIN_DIR})/log" + +# define logfile and logging +LOG_BASE=${LOG_BASE:-"${TVDLDAP_LOG_DIR}"} # Use script log directory as default logbase +TIMESTAMP=$(date "+%Y.%m.%d_%H%M%S") +readonly LOGFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$TIMESTAMP.log" + +# define tempfile for ldapsearch +TEMPFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$$.ldif" +# - EOF Environment Variables ----------------------------------------------- + +# - Functions --------------------------------------------------------------- +# --------------------------------------------------------------------------- +# Function...: Usage +# Purpose....: Display Usage and exit script +# --------------------------------------------------------------------------- +function Usage() { + + # define default values for function arguments + error=${1:-"0"} # default error number + error_value=${2:-""} # default error message + cat << EOI + + Usage: ${TVDLDAP_SCRIPT_NAME} [options] [bind options] [search options] [services] + + where: + services Comma separated list of Oracle Net Service Names to search + + Common Options: + -m Usage this message + -v Enable verbose mode (default \$TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE}) + -d Enable debug mode (default \$TVDLDAP_DEBUG=${TVDLDAP_DEBUG}) + -b Specify Base DN to search Net Service Name. Either + specific base DN or ALL to search Net Service Name in + all available namingContexts. By the default the Base + DN is derived from a fully qualified Net Service Name. + Otherwise the default Base DN is taken from ldap.ora. Can + also be specified by setting TVDLDAP_BASEDN. + -h LDAP server (default take from ldap.ora). Can be specified + by setting TVDLDAP_LDAPHOST. + -p port on LDAP server (default take from ldap.ora). Can be + specified by setting TVDLDAP_LDAPPORT. + + Bind Options: + -D Bind DN (default ANONYMOUS). Can be specified by setting + TVDLDAP_BINDDN. + -w Bind password. Can be specified by setting TVDLDAP_BINDDN_PWD. + -W prompt for bind password. Can be specified by setting + TVDLDAP_BINDDN_PWDASK. + -y Read password from file. Can be specified by setting + TVDLDAP_BINDDN_PWDFILE. + + Search options: + -S Oracle Net Service Names to search for + (default \$ORACLE_SID) + + Configuration file: + The script does load configuration files to define default values as an + alternative for command line parameter. e.g. to set a bind DN TVDLDAP_BINDDN + LDAP hostname TVDLDAP_LDAPHOST, etc. The configuration files are loaded in + the following order: + + 1. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}.conf + 2. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}_custom.conf + 3. ${ETC_BASE}/${TOOL_BASE_NAME}.conf + 4. ${ETC_BASE}/${TOOL_BASE_NAME}_custom.conf + 5. Command line parameter + + Logfile : ${LOGFILE} + +EOI + dump_runtime_config # dump current tool specific environment in debug mode + clean_quit ${error} ${error_value} +} +# - EOF Functions ----------------------------------------------------------- + +# - Initialization ---------------------------------------------------------- +touch $LOGFILE 2>/dev/null # initialize logfile +exec &> >(tee -a "$LOGFILE") # Open standard out at `$LOG_FILE` for write. +exec 2>&1 +echo "INFO : Start ${TVDLDAP_SCRIPT_NAME} on host $(hostname) at $(date)" + +# source common variables and functions from tns_functions.sh +if [ -f ${TVDLDAP_BIN_DIR}/tns_functions.sh ]; then + . ${TVDLDAP_BIN_DIR}/tns_functions.sh +else + echo "ERROR: Can not find common functions ${TVDLDAP_BIN_DIR}/tns_functions.sh" + exit 5 +fi + +load_config # load configur26ation files. File list in TVDLDAP_CONFIG_FILES + +# initialize tempfile for ldapsearch output +touch $TEMPFILE 2>/dev/null || clean_quit 25 $TEMPFILE + +# get options +while getopts mvdb:h:p:D:w:Wy:S:E: CurOpt; do + case ${CurOpt} in + m) Usage 0;; + v) TVDLDAP_VERBOSE="TRUE" ;; + d) TVDLDAP_DEBUG="TRUE" ;; + b) TVDLDAP_BASEDN="${OPTARG}";; + h) TVDLDAP_LDAPHOST=${OPTARG};; + p) TVDLDAP_LDAPPORT=${OPTARG};; + D) TVDLDAP_BINDDN="${OPTARG}";; + w) TVDLDAP_BINDDN_PWD="${OPTARG}";; + W) TVDLDAP_BINDDN_PWDASK="TRUE";; + y) TVDLDAP_BINDDN_PWDFILE="${OPTARG}";; + S) NETSERVICE=${OPTARG};; + E) clean_quit "${OPTARG}";; + *) Usage 2 $*;; + esac +done + +# display usage and exit if parameter is null +if [ $# -eq 0 ]; then + Usage 1 +fi + +check_tools # check if we do have the required LDAP tools available +check_ldap_tools # check what kind of LDAP tools we do have e.g. + # OpenLDAP, Oracle DB or Oracle Unified Directory +dump_runtime_config # dump current tool specific environment in debug mode + +# get the ldapsearch options based on available tools +ldapsearch_options=$(ldapsearch_options) + +# Default values +export NETSERVICE=${NETSERVICE:-""} + +# check for Service and Arguments +if [ -z "$NETSERVICE" ] && [ $# -ne 0 ]; then + if [[ "$1" =~ ^-.* ]]; then + NETSERVICE=$ORACLE_SID # default service to ORACLE_SID if Argument starting with dash + else + NETSERVICE=$1 # default service to Argument if not starting with dash + fi +fi + +# check for mandatory parameters +if [ -z "${NETSERVICE}" ]; then clean_quit 3 "-S"; fi + +# get default values for LDAP Server +TVDLDAP_LDAPHOST=${TVDLDAP_LDAPHOST:-$(get_ldaphost)} +TVDLDAP_LDAPPORT=${TVDLDAP_LDAPPORT:-$(get_ldapport)} + +# get bind parameter +ask_bindpwd # ask for the bind password if TVDLDAP_BINDDN_PWDASK + # is TRUE and LDAP tools are not OpenLDAP +current_binddn=$(get_binddn_param "$TVDLDAP_BINDDN" ) +current_bindpwd=$(get_bindpwd_param "$TVDLDAP_BINDDN_PWD" ${TVDLDAP_BINDDN_PWDASK} "$TVDLDAP_BINDDN_PWDFILE") +if [ -n "$current_binddn" ] && [ -z "${current_bindpwd}" ]; then clean_quit 4; fi + +# get base DN information +BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") +# - EOF Initialization ------------------------------------------------------- + +# - Main --------------------------------------------------------------------- +echo_debug "DEBUG: Configuration / Variables:" +echo_debug "DEBUG: LDAP Host............... = $TVDLDAP_LDAPHOST" +echo_debug "DEBUG: LDAP Port............... = $TVDLDAP_LDAPPORT" +echo_debug "DEBUG: Bind DN................. = $TVDLDAP_BINDDN" +echo_debug "DEBUG: Bind PWD................ = $TVDLDAP_BINDDN_PWD" +echo_debug "DEBUG: Bind PWD File........... = $TVDLDAP_BINDDN_PWDFILE" +echo_debug "DEBUG: Bind parameter.......... = $current_binddn $current_bindpwd" +echo_debug "DEBUG: Base DN................. = $BASEDN_LIST" +echo_debug "DEBUG: Net Service Names....... = $NETSERVICE" +echo_debug "DEBUG: ldapsearch options...... = $ldapsearch_options" + +for service in $(echo $NETSERVICE | tr "," "\n"); do # loop over service + echo_debug "DEBUG: process service $service" + current_basedn=$(split_net_service_basedn ${service}) + current_cn=$(split_net_service_cn ${service}) + + # Set BASEDN_LIST to current Base DN taken from Net Service Name + if [ -n "${current_basedn}" ]; then + BASEDN_LIST=${current_basedn} + else + BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") + fi + + echo_debug "DEBUG: current Base DN list........ = $BASEDN_LIST" + echo_debug "DEBUG: current Net Service Names... = $current_cn" + for basedn in ${BASEDN_LIST}; do # loop over base DN + if basedn_exists ${basedn}; then + echo "INFO : Process base dn $basedn" + domain=$(echo $basedn|sed -e 's/,dc=/\./g' -e 's/dc=//g') + if ! alias_enabled; then + # run ldapsearch an write output to tempfile + ldapsearch -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} ${current_bindpwd} \ + ${ldapsearch_options} -b "$basedn" -s sub \ + "(&(cn=${current_cn})(|(objectClass=orclNetService)(objectClass=orclService)(objectClass=orclNetServiceAlias)))" \ + cn orclNetDescString aliasedObjectName>$TEMPFILE + # check if last command did run successfully + if [ $? -ne 0 ]; then clean_quit 33 "ldapsearch"; fi + fi + # check if tempfile does exist and has some values + if [ -s "$TEMPFILE" ]; then + echo "" >> $TEMPFILE # add a new line to the tempfile + # loop over ldapsearch results + for result in $(grep -iv '^dn: ' $TEMPFILE | sed -n '1 {h; $ !d}; $ {x; s/\n //g; p}; /^ / {H; d}; /^ /! {x; s/\n //g; p}'| sed 's/$/;/g' | sed 's/^;$/DELIM/g' | tr -d '\n'| sed 's/DELIM/\n/g'|tr -d ' '); do + echo_debug "DEBUG: ${result}" + cn=$(echo ${result}| cut -d ';' -f 1 | cut -d " " -f 2 | sed 's/cn://gi') + # check for aliasedObjectName or orclNetDescString + if [[ "$result" == *orclNetDescString* ]]; then + NetDescString=$(echo ${result}| cut -d ';' -f 2 | cut -d " " -f2- |sed 's/orclNetDescString://gi') + echo "${cn}.${domain}=${NetDescString}" + elif [[ "$result" == *aliasedObjectName* ]]; then + aliasedObjectName=$(echo ${result}| cut -d ';' -f 2 | cut -d " " -f2- |sed 's/aliasedObjectName://gi') + echo "${cn}.${domain} alias to ${aliasedObjectName}" + fi + done + else + echo "WARN : Net Service Name / Alias ${current_cn} not found in ${basedn}" + fi + echo "" + else + echo "WARN : Base DN ${basedn} not found" + fi + done +done + +rotate_logfiles # purge log files based on TVDLDAP_KEEP_LOG_DAYS +clean_quit # clean exit with return code 0 +# --- EOF -------------------------------------------------------------------- diff --git a/bin/tns_test.sh b/bin/tns_test.sh new file mode 100755 index 0000000..41b1195 --- /dev/null +++ b/bin/tns_test.sh @@ -0,0 +1,372 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tns_test.sh +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: Test LDAP entries using tnsping and sqlplus +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# - Customization ------------------------------------------------------------ +# - just add/update any kind of customized environment variable here + +# - End of Customization ---------------------------------------------------- + +# Define a bunch of bash option see +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o nounset # exit if script try to use an uninitialised variable +# set -o errexit # exit script if any statement returns a non-true return value +# set -o pipefail # pipefail exit after 1st piped commands failed + +# - Environment Variables --------------------------------------------------- +# define generic environment variables +VERSION=v0.1.0 +TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE:-"FALSE"} # enable verbose mode +TVDLDAP_DEBUG=${TVDLDAP_DEBUG:-"FALSE"} # enable debug mode +TVDLDAP_QUIET=${TVDLDAP_QUIET:-"FALSE"} # enable quiet mode +TVDLDAP_SCRIPT_NAME=$(basename ${BASH_SOURCE[0]}) +TVDLDAP_BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +TVDLDAP_LOG_DIR="$(dirname ${TVDLDAP_BIN_DIR})/log" +padding='.................................................' +# define logfile and logging +LOG_BASE=${LOG_BASE:-"${TVDLDAP_LOG_DIR}"} # Use script log directory as default logbase +TIMESTAMP=$(date "+%Y.%m.%d_%H%M%S") +readonly LOGFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$TIMESTAMP.log" + +# define tempfile for ldapsearch +TEMPFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_$$.ldif" +TNSPING_TEMPFILE="$LOG_BASE/$(basename $TVDLDAP_SCRIPT_NAME .sh)_tnsping_$$.log" +# - EOF Environment Variables ----------------------------------------------- + +# - Functions --------------------------------------------------------------- +# --------------------------------------------------------------------------- +# Function...: Usage +# Purpose....: Display Usage and exit script +# --------------------------------------------------------------------------- +function Usage() { + + # define default values for function arguments + error=${1:-"0"} # default error number + error_value=${2:-""} # default error message + cat << EOI + + Usage: ${TVDLDAP_SCRIPT_NAME} [options] [test options] [bind options] [search options] [services] + + where: + services Comma separated list of Oracle Net Service Names to test + + Common Options: + -m Usage this message + -v Enable verbose mode (default \$TVDLDAP_VERBOSE=${TVDLDAP_VERBOSE}) + -d Enable debug mode (default \$TVDLDAP_DEBUG=${TVDLDAP_DEBUG}) + -b Specify Base DN to search Net Service Name. Either + specific base DN or ALL to search Net Service Name in + all available namingContexts. By the default the Base + DN is derived from a fully qualified Net Service Name. + Otherwise the default Base DN is taken from ldap.ora. Can + also be specified by setting TVDLDAP_BASEDN. + -h LDAP server (default take from ldap.ora). Can be specified + by setting TVDLDAP_LDAPHOST. + -p port on LDAP server (default take from ldap.ora). Can be + specified by setting TVDLDAP_LDAPPORT. + -t Specific a timeout for the test commands using core utility + timeout. DURATION is a number with an optional suffix: 's' + for seconds (the default), 'm' for minutes, 'h' for + hours or 'd' for days. A duration of 0 disables the + associated timeout. + + Test Options: + -U Username for SQLPlus test. If no username is specified, + the SQLPlus test will be omitted. Can be specified by + setting TVDLDAP_SQL_USER. + -c SQLPlus password. Can be specified by setting TVDLDAP_SQL_PWD. + -C prompt for SQLPlus password. Can be specified by setting + TVDLDAP_SQL_PWDASK. + -Z Read password from file. Can be specified by setting + TVDLDAP_SQL_PWDFILE. + + Bind Options: + -D Bind DN (default ANONYMOUS). Can be specified by setting + TVDLDAP_BINDDN. + -w Bind password. Can be specified by setting TVDLDAP_BINDDN_PWD. + -W prompt for bind password. Can be specified by setting + TVDLDAP_BINDDN_PWDASK. + -y Read password from file. Can be specified by setting + TVDLDAP_BINDDN_PWDFILE. + + Search options: + -S Oracle Net Service Names to search for + (default \$ORACLE_SID) + + Configuration file: + The script does load configuration files to define default values as an + alternative for command line parameter. e.g. to set a bind DN TVDLDAP_BINDDN + LDAP hostname TVDLDAP_LDAPHOST, etc. The configuration files are loaded in + the following order: + + 1. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}.conf + 2. ${TVDLDAP_ETC_DIR}/${TOOL_BASE_NAME}_custom.conf + 3. ${ETC_BASE}/${TOOL_BASE_NAME}.conf + 4. ${ETC_BASE}/${TOOL_BASE_NAME}_custom.conf + 5. Command line parameter + + Logfile : ${LOGFILE} + +EOI + dump_runtime_config # dump current tool specific environment in debug mode + clean_quit ${error} ${error_value} +} +# - EOF Functions ----------------------------------------------------------- + +# - Initialization ---------------------------------------------------------- +touch $LOGFILE 2>/dev/null # initialize logfile +exec &> >(tee -a "$LOGFILE") # Open standard out at `$LOG_FILE` for write. +exec 2>&1 +echo "INFO : Start ${TVDLDAP_SCRIPT_NAME} on host $(hostname) at $(date)" + +# source common variables and functions from tns_functions.sh +if [ -f ${TVDLDAP_BIN_DIR}/tns_functions.sh ]; then + . ${TVDLDAP_BIN_DIR}/tns_functions.sh +else + echo "ERROR: Can not find common functions ${TVDLDAP_BIN_DIR}/tns_functions.sh" + exit 5 +fi + +load_config # load configur26ation files. File list in TVDLDAP_CONFIG_FILES + +# initialize tempfile for ldapsearch output +touch $TEMPFILE 2>/dev/null || clean_quit 25 $TEMPFILE +touch $TNSPING_TEMPFILE 2>/dev/null || clean_quit 25 $TNSPING_TEMPFILE + +# get options +while getopts mvdb:h:p:D:w:Wy:E:t:U:c:CZ:S: CurOpt; do + case ${CurOpt} in + m) Usage 0;; + v) TVDLDAP_VERBOSE="TRUE" ;; + d) TVDLDAP_DEBUG="TRUE" ;; + b) TVDLDAP_BASEDN="${OPTARG}";; + h) TVDLDAP_LDAPHOST=${OPTARG};; + p) TVDLDAP_LDAPPORT=${OPTARG};; + D) TVDLDAP_BINDDN="${OPTARG}";; + w) TVDLDAP_BINDDN_PWD="${OPTARG}";; + W) TVDLDAP_BINDDN_PWDASK="TRUE";; + y) TVDLDAP_BINDDN_PWDFILE="${OPTARG}";; + t) TVDLDAP_TIMEMOUT="${OPTARG}";; + U) TVDLDAP_SQL_USER="${OPTARG}";; + c) TVDLDAP_SQL_PWD="${OPTARG}";; + C) TVDLDAP_SQL_PWDASK="TRUE";; + Z) TVDLDAP_SQL_PWDFILE="${OPTARG}";; + S) NETSERVICE=${OPTARG};; + E) clean_quit "${OPTARG}";; + *) Usage 2 $*;; + esac +done + +check_tools # check if we do have the required LDAP tools available +check_ldap_tools # check what kind of LDAP tools we do have e.g. + # OpenLDAP, Oracle DB or Oracle Unified Directory +dump_runtime_config # dump current tool specific environment in debug mode + +# get the ldapsearch options based on available tools +ldapsearch_options=$(ldapsearch_options) + +# check if we do hav a tnsping +if ! command_exists tnsping; then + clean_quit 10 tnsping +fi + +# check if we do hav a sqlplus +if ! command_exists sqlplus; then + clean_quit 10 sqlplus +fi + +# Default values +export NETSERVICE=${NETSERVICE:-""} + +# check for Service and Arguments +if [ -z "$NETSERVICE" ] && [ $# -ne 0 ]; then + echo_debug "DEBUG: Process default NETSERVICE" + if [[ "$1" =~ ^-.* ]]; then + echo_debug "DEBUG: Set NETSERVICE to ALL" + NETSERVICE="ALL" # default service to * if Argument starting with dash + else + echo_debug "DEBUG: Set NETSERVICE to $1" + NETSERVICE=$1 # default service to Argument if not starting with dash + fi +else + echo_debug "DEBUG: Set NETSERVICE to ALL" + NETSERVICE=${NETSERVICE:-"ALL"} +fi + +# get default values for LDAP Server +TVDLDAP_LDAPHOST=${TVDLDAP_LDAPHOST:-$(get_ldaphost)} +TVDLDAP_LDAPPORT=${TVDLDAP_LDAPPORT:-$(get_ldapport)} + +# default time out setting +TVDLDAP_TIMEMOUT=${TVDLDAP_TIMEMOUT:-0} + +# Check if timeout is defined and verify timeout command +if [ -n "$TVDLDAP_TIMEMOUT" ] && [ $TVDLDAP_TIMEMOUT -ne 0 ]; then + if ! command_exists timeout; then + clean_quit 10 timeout + fi + timeout_command="timeout $TVDLDAP_TIMEMOUT" +else + echo "INFO : Skip test timeout as duration is set to $TVDLDAP_TIMEMOUT." + timeout_command="" +fi + +# get bind parameter +ask_bindpwd # ask for the bind password if TVDLDAP_BINDDN_PWDASK + # is TRUE and LDAP tools are not OpenLDAP +current_binddn=$(get_binddn_param "$TVDLDAP_BINDDN" ) +current_bindpwd=$(get_bindpwd_param "$TVDLDAP_BINDDN_PWD" ${TVDLDAP_BINDDN_PWDASK} "$TVDLDAP_BINDDN_PWDFILE") +if [ -n "$current_binddn" ] && [ -z "${current_bindpwd}" ]; then clean_quit 4; fi + +# get the SQL test password if user name is defined +if [ -n "$TVDLDAP_SQL_USER" ]; then + if [ -z "$TVDLDAP_SQL_PWD" ]; then + # try to get the password from file if TVDLDAP_SQL_PWD is empty + if [ -f "$TVDLDAP_SQL_PWDFILE" ]; then + TVDLDAP_SQL_PWD=$(cat $TVDLDAP_SQL_PWDFILE) + elif [ "${TVDLDAP_SQL_PWDASK^^}" == "TRUE" ]; then + read -p "SQLPlus Password:" TVDLDAP_SQL_PWD + else + echo "WARN : No password defined. Using dummy password to run SQLPlus tests." + TVDLDAP_SQL_PWD="tiger" + fi + fi +else + echo "WARN : Skip SQLPlus test. No user name defined." +fi + +# get base DN information +BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") +# - EOF Initialization ------------------------------------------------------- + +# - Main --------------------------------------------------------------------- +echo_debug "DEBUG: Configuration / Variables:" +echo_debug "DEBUG: LDAP Host............... = $TVDLDAP_LDAPHOST" +echo_debug "DEBUG: LDAP Port............... = $TVDLDAP_LDAPPORT" +echo_debug "DEBUG: Bind DN................. = $TVDLDAP_BINDDN" +echo_debug "DEBUG: Bind PWD................ = $TVDLDAP_BINDDN_PWD" +echo_debug "DEBUG: Bind PWD File........... = $TVDLDAP_BINDDN_PWDFILE" +echo_debug "DEBUG: Bind parameter.......... = $current_binddn $current_bindpwd" +echo_debug "DEBUG: Base DN................. = $BASEDN_LIST" +echo_debug "DEBUG: Net Service Names....... = $NETSERVICE" +echo_debug "DEBUG: ldapsearch options...... = $ldapsearch_options" +echo_debug "DEBUG: Command Timeout......... = $TVDLDAP_TIMEMOUT" +echo_debug "DEBUG: SQL Test User........... = $TVDLDAP_SQL_USER" +echo_debug "DEBUG: SQL Test PWD............ = $TVDLDAP_SQL_PWD" +echo_debug "DEBUG: SQL Test PWD File....... = $TVDLDAP_SQL_PWDFILE" + +for service in $(echo $NETSERVICE | tr "," "\n"); do # loop over service + echo_debug "DEBUG: process service $service" + # set current_cn to * for all + if [ "${NETSERVICE^^}" == "ALL" ]; then + current_basedn="" + current_cn="*" + echo_debug "DEBUG: current Net Service Names = $NETSERVICE" + else + current_basedn=$(split_net_service_basedn ${service}) + current_cn=$(split_net_service_cn ${service}) + echo_debug "DEBUG: current Net Service Names = $current_cn" + fi + + # Set BASEDN_LIST to current Base DN taken from Net Service Name + if [ -n "${current_basedn}" ]; then + BASEDN_LIST=${current_basedn} + else + BASEDN_LIST=$(get_basedn "$TVDLDAP_BASEDN") + fi + + echo_debug "DEBUG: current Base DN list........ = $BASEDN_LIST" + for basedn in ${BASEDN_LIST}; do # loop over base DN + if basedn_exists ${basedn}; then + echo "INFO : Process base dn $basedn" + domain=$(echo $basedn|sed -e 's/,dc=/\./g' -e 's/dc=//g') + # run ldapsearch an write output to tempfile + ldapsearch -h ${TVDLDAP_LDAPHOST} -p ${TVDLDAP_LDAPPORT} \ + ${current_binddn:+"$current_binddn"} ${current_bindpwd} \ + ${ldapsearch_options} -b "$basedn" -s sub \ + "(&(cn=${current_cn})(|(objectClass=orclNetService)(objectClass=orclService)(objectClass=orclNetServiceAlias)))" \ + cn orclNetDescString aliasedObjectName>$TEMPFILE + if [ $? -ne 0 ]; then + clean_quit 33 "ldapsearch" + fi + # check if tempfile does exist and has some values + if [ -s "$TEMPFILE" ] ; then + echo "" >> $TEMPFILE # add a new line to the tempfile + # loop over ldapsearch results + for result in $(grep -iv '^dn: ' $TEMPFILE | sed -n '1 {h; $ !d}; $ {x; s/\n //g; p}; /^ / {H; d}; /^ /! {x; s/\n //g; p}'| sed 's/$/;/g' | sed 's/^;$/DELIM/g' | tr -d '\n'| sed 's/DELIM/\n/g'|tr -d ' '); do + + cn=$(echo ${result}| cut -d ';' -f 1 | cut -d " " -f 2 | sed 's/cn://gi') + if [[ "$result" == *orclNetDescString* ]]; then + NetDescString=$(echo ${result}| cut -d ';' -f 2 | cut -d " " -f2- |sed 's/orclNetDescString://gi') + elif [[ "$result" == *aliasedObjectName* ]]; then + NetDescString=$(echo ${result}| cut -d ';' -f 2 | cut -d " " -f2- |sed 's/aliasedObjectName://gi') + NetDescString="$(split_net_service_cn ${NetDescString}).${domain}" + fi + + NetDescString=$(echo ${result}| cut -d ';' -f 2 | cut -d " " -f2- |sed 's/orclNetDescString://gi') + current_netservice="${cn}.${domain}" + + # add a few debug messages + echo_debug "DEBUG: ${result}" + echo_debug "DEBUG: cn.............. : $cn" + echo_debug "DEBUG: NetDescString... : $NetDescString" + + # run tnsping checks for the Net Service Connect String + printf "INFO : Test Net Service Connect String for %s %s" "${current_netservice}" "${padding:${#current_netservice}}" + tnsping_error=0 + $timeout_command tnsping "${NetDescString}" >$TNSPING_TEMPFILE 2>&1 || tnsping_error=$? + TNSPING_STATUS=$(cat $TNSPING_TEMPFILE ) + if [[ $tnsping_error -ne 0 ]] || [[ $TNSPING_STATUS == *"TNS-"* ]]; then + # Handle error if tnsping return something with TNS- + TNSERR=$(echo "$TNSPING_STATUS"|sed -n 's/.*\(TNS\-[0-9]*\).*/\1/p') + TNSERR=${TNSERR:-"timed out ${TVDLDAP_TIMEMOUT}s"} + echo "NOK ($TNSERR)" + echo "# tnsping error/timeout $TNSERR" >>"$(dirname $LOGFILE)/$(basename $LOGFILE .log).errors.log" + echo "${cn}.${domain}=${NetDescString}" >>"$(dirname $LOGFILE)/$(basename $LOGFILE .log).errors.log" + else + # Prozess sqlplus check if a login user is defined and tnsping does not create an error + if [ -n "$TVDLDAP_SQL_USER" ] && [ -n "$TVDLDAP_SQL_PWD" ]; then +SQLPLUS_STATUS=$(sqlplus -S -L /nolog <>"$(dirname $LOGFILE)/$(basename $LOGFILE .log).errors.log" + echo "${cn}.${domain}=${NetDescString}" >>"$(dirname $LOGFILE)/$(basename $LOGFILE .log).errors.log" + fi + else + echo "OK (tnsping)" + fi + fi + done + else + echo "WARN : No service found in ${basedn}" + fi + else + echo "WARN : Base DN ${basedn} not found" + fi + done +done + +rotate_logfiles # purge log files based on TVDLDAP_KEEP_LOG_DAYS +clean_quit # clean exit with return code 0 +# --- EOF -------------------------------------------------------------------- diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..ecdc859 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,53 @@ +# Documentation + +This folder contains the documentation files and folder. + +- [doc](./README.md) documentation files. +- [images](./images/README.md) Images and logo files. +- [metadata.yml](./metadata.yml) Meta file used during pandoc conversion. This + file include different information like, title, subtile, author, fonts etc + +## Build Documentation + +The workshop documentation is based on markdown. This allows to convert it to +different formats e.g. PDF, DOCX and PPTX + +- Create PDF using a docker container. + +```bash +docker run --rm -v "$PWD":/workdir:z oehrlis/pandoc \ +--metadata-file=doc/metadata.yml \ +--listings --pdf-engine=xelatex \ +--resource-path=images --filter pandoc-latex-environment \ +--output=tvd-ldap-doc.pdf doc/?x??-*.md +``` + +- Create DOCX using a local *pandoc* installation. + +```bash +pandoc --reference-doc doc/templates/trivadis.docx --listings \ +--metadata-file=doc/metadata.yml \ +--resource-path images \ +-o tvd-ldap-doc.docx \ +doc/?x??-*.md +``` + +- Create Markdown file using a local pandoc installation. + +```bash +pandoc --listings \ +--metadata-file=doc/metadata.yml \ +--resource-path images \ +-o tvd-ldap-doc.md \ +doc/?x??-*.md +``` + +- Create HTML file using a local pandoc installation. + +```bash +pandoc -f markdown --listings \ +--metadata-file=doc/metadata.yml \ +--resource-path images --standalone \ +-o tvd-ldap-doc.html --css doc/templates/pandoc.css \ +doc/?x??-*.md +``` diff --git a/doc/images/README.md b/doc/images/README.md new file mode 100644 index 0000000..abac0ff --- /dev/null +++ b/doc/images/README.md @@ -0,0 +1,7 @@ +# Images and Logo Files + +This folder contains various images and logo files that are used in this good +practice guide. Make sure to include the proper resource path in you markdown +files to either display the images in markdown as well to generate the different +output formats using *pandoc*. It may be necessary to use the *pandoc* parameter +`--resource-path`. diff --git a/etc/README.md b/etc/README.md new file mode 100644 index 0000000..12476fb --- /dev/null +++ b/etc/README.md @@ -0,0 +1,10 @@ +# Configuration Files + +This directory contains miscellaneous configuration files used in this project. + +- [oraNet.inf_template](./oraNet.inf_template) template file to setup a + *389 Directory Server*. +- [tvdldap.conf](./tvdldap.conf) *TVD-LDAP* configuration file for the default values. +- [tvdldap_custom.template.conf](./tvdldap_custom.template.conf) *TVD-LDAP* + template for custom configuration file. + \ No newline at end of file diff --git a/etc/oraNet.inf_template b/etc/oraNet.inf_template new file mode 100644 index 0000000..5d6fa37 --- /dev/null +++ b/etc/oraNet.inf_template @@ -0,0 +1,33 @@ +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: oraNet.inf +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2021.12.07 +# Revision...: +# Purpose....: Init Configuration file for 389-ds +# Notes......: create a new template file by running +# dscreate create-template oraNet_template.inf +# Reference..: https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html/administration_guide/creating_a_new_ds_instance +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- + +[general] +full_machine_name = +start = True + +[slapd] +instance_name = oraNet +port = 389 +root_password = +secure_port = 636 +self_sign_cert = True +self_sign_cert_valid_months = 24 + +[backend-userroot] +create_suffix_entry = True +suffix = +# --- EOF -------------------------------------------------------------------- \ No newline at end of file diff --git a/etc/tvdldap.conf b/etc/tvdldap.conf new file mode 100644 index 0000000..2703c53 --- /dev/null +++ b/etc/tvdldap.conf @@ -0,0 +1,38 @@ +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tvdldap.conf +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: TVD-LDAP Configuration file +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# export TVDLDAP_LDAPHOST="localhost" # Default LDAP host. If omitted, it is derived from ldap.ora +# export TVDLDAP_LDAPPORT=389 # Default LDAP port. If omitted, it is derived from ldap.ora +# export TVDLDAP_BASEDN="" # Default base DN used for the LDAP tools + +export TVDLDAP_BINDDN="" # Default Bind DN to used for the LDAP tools +export TVDLDAP_BINDDN_PWDASK="FALSE" # Flag to enable interactiv Password e.g. -W +export TVDLDAP_BINDDN_PWD="" # Bind Password, possible but not a good idea to store it here +export TVDLDAP_BINDDN_PWDFILE="" # Path to password file + +# export TVDLDAP_SQL_USER="system" # Default SQL Plus user used test connect strings +# export TVDLDAP_SQL_PWD="" # SQL Plus password, to test connect strings. It is possible but not a good idea to store it here +# export TVDLDAP_SQL_PWDASK="FALSE" # Flag to enable interactiv Password e.g. -W +# export TVDLDAP_SQL_PWDFILE="" # Path to password file for SQL Plus tests + +export TVDLDAP_KEEP_LOG_DAYS=14 # amount of days to keep the logfiles +# export TVDLDAP_LDAPTOOLS="" # define default LDAP utilities. Will be overwritten by check_ldap_tools +# export TVDLDAP_VERBOSE="FALSE" # enable verbose mode +# export TVDLDAP_DEBUG="FALSE" # enable debug mode +# export TVDLDAP_QUIET="FALSE" # enable quiet mode +# export TVDLDAP_FORCE="FALSE" # enable force mode to overwrite existing entries +# export TVDLDAP_DRYRUN="FALSE" # enable dry run mode to show what would be done but do not actually do it +export TVDLDAP_TIMEMOUT=1 # define default timeout for testing +# --- EOF -------------------------------------------------------------------- \ No newline at end of file diff --git a/etc/tvdldap_custom.template.conf b/etc/tvdldap_custom.template.conf new file mode 100644 index 0000000..efe3217 --- /dev/null +++ b/etc/tvdldap_custom.template.conf @@ -0,0 +1,39 @@ +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: tvdldap_custom.template.conf +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2022.02.23 +# Revision...: +# Purpose....: TVD-LDAP custom configuration file template. Just copy the file +# to $etc/tvdldap_custom.conf and adjust the values. +# Notes......: -- +# Reference..: -- +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# export TVDLDAP_LDAPHOST="localhost" # Default LDAP host. If omitted, it is derived from ldap.ora +# export TVDLDAP_LDAPPORT=389 # Default LDAP port. If omitted, it is derived from ldap.ora +# export TVDLDAP_BASEDN="" # Default base DN used for the LDAP tools + +# export TVDLDAP_BINDDN="" # Default Bind DN to used for the LDAP tools +# export TVDLDAP_BINDDN_PWDASK="FALSE" # Flag to enable interactiv Password e.g. -W +# export TVDLDAP_BINDDN_PWD="" # Bind Password, possible but not a good idea to store it here +# export TVDLDAP_BINDDN_PWDFILE="" # Path to password file + +# export TVDLDAP_SQL_USER="system" # Default SQL Plus user used test connect strings +# export TVDLDAP_SQL_PWD="" # SQL Plus password, to test connect strings. It is possible but not a good idea to store it here +# export TVDLDAP_SQL_PWDASK="FALSE" # Flag to enable interactiv Password e.g. -W +# export TVDLDAP_SQL_PWDFILE="" # Path to password file for SQL Plus tests + +# export TVDLDAP_KEEP_LOG_DAYS=14 # amount of days to keep the logfiles +# export TVDLDAP_LDAPTOOLS="" # define default LDAP utilities. Will be overwritten by check_ldap_tools +# export TVDLDAP_VERBOSE="FALSE" # enable verbose mode +# export TVDLDAP_DEBUG="FALSE" # enable debug mode +# export TVDLDAP_QUIET="FALSE" # enable quiet mode +# export TVDLDAP_FORCE="FALSE" # enable force mode to overwrite existing entries +# export TVDLDAP_DRYRUN="FALSE" # enable dry run mode to show what would be done but do not actually do it +# export TVDLDAP_TIMEMOUT=1 # define default timeout for testing +# --- EOF -------------------------------------------------------------------- \ No newline at end of file diff --git a/ldif/90orclNet.ldif b/ldif/90orclNet.ldif new file mode 100644 index 0000000..dda87ae --- /dev/null +++ b/ldif/90orclNet.ldif @@ -0,0 +1,61 @@ +dn: cn=schema +objectClass: top +objectClass: ldapSubentry +objectClass: subschema +cn: schema +attributeTypes: ( 2.16.840.1.113894.7.1.6 NAME 'orclProductVersion' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +attributeTypes: ( 2.16.840.1.113894.1.1.320 NAME 'orclAppFullName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.1.1.318 NAME 'orclApplicationAddress' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.1.1.319 NAME 'orclApplicationCommonName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.1.1.317 NAME 'orclCategory' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications ) +attributetypes: ( 2.16.840.1.113894.2.1.10 NAME 'orclDBGlobalName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113894.1.1.347 NAME 'orclDBSchemaIdentifier' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE userApplications ) +attributetypes: ( 2.16.840.1.113894.2.1.1 NAME 'orclDBtrustedUser' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) +attributeTypes: ( 2.16.840.1.113894.3.1.14 NAME 'orclNetAddressString' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.17 NAME 'orclNetAddrList' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.21 NAME 'orclNetAuthenticationService' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.10 NAME 'orclNetAuthenticationType' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.11 NAME 'orclNetAuthParams' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.20 NAME 'orclNetConnParamList' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications ) +attributetypes: ( 2.16.840.1.113894.3.1.19 NAME 'orclNetDescList' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications ) +attributetypes: ( 2.16.840.1.113894.3.1.12 NAME 'orclNetDescName' EQUALITY DistinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +attributetypes: ( 2.16.840.1.113894.3.1.13 NAME 'orclNetDescString' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributeTypes: ( 2.16.840.1.113894.3.1.3 NAME 'orclNetFailover' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.24 NAME 'orclNetFailoverModeString' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.8 NAME 'orclNetHandlerName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributetypes: ( 2.16.840.1.113894.3.1.26 NAME 'orclNetHostname' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.7 NAME 'orclNetInstanceName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications )Name +attributeTypes: ( 2.16.840.1.113894.3.1.25 NAME 'orclNetInstanceRole' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.2 NAME 'orclNetLoadBalance' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.9 NAME 'orclNetParamList' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.15 NAME 'orclNetProtocol' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.18 NAME 'orclNetProtocolStack' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.23 NAME 'orclNetReceiveBufSize' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.4 NAME 'orclNetSdu' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.22 NAME 'orclNetSendBufSize' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.5 NAME 'orclNetServer' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.6 NAME 'orclNetServiceName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.16 NAME 'orclNetShared' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE userApplications ) +attributeTypes: ( 2.16.840.1.113894.3.1.1 NAME 'orclNetSourceRoute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE USAGE userApplications ) +attributetypes: ( 2.16.840.1.113894.7.1.2 NAME 'orclOracleHome' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributetypes: ( 2.16.840.1.113894.1.1.210 NAME 'orclPasswordVerifier' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) +attributetypes: ( 1.3.6.1.4.1.4203.1.3.4 NAME 'authPassword' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) +attributeTypes: ( 2.16.840.1.113894.1.1.348 NAME 'orclResourceIdentifier' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE userApplications ) +attributetypes: ( 2.16.840.1.113894.7.1.4 NAME 'orclServiceType' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributetypes: ( 2.16.840.1.113894.7.1.5 NAME 'orclSid' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributetypes: ( 2.16.840.1.113894.7.1.3 NAME 'orclSystemName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +attributetypes: ( 2.16.840.1.113894.7.1.1 NAME 'orclVersion' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +objectClasses: ( 2.16.840.1.113894.7.2.2 NAME 'orclContainer' SUP top STRUCTURAL MUST cn ) +objectClasses: ( 2.16.840.1.113894.7.2.3 NAME 'orclContext' SUP top STRUCTURAL MUST cn ) +objectClasses: ( 2.16.840.1.113894.7.2.6 NAME 'orclSchemaVersion' SUP top STRUCTURAL MUST ( cn $ orclProductVersion ) ) +objectClasses: ( 2.16.840.1.113894.1.2.55 NAME 'orclApplicationEntity' SUP top MAY ( orclApplicationCommonName $ orclAppFullName $ description $ seeAlso $ orclVersion $ orclCategory $ userPassword $ authPassword $ orclPasswordVerifier $ userPKCS12 $ userCertificate $ labeledURI $ orclApplicationAddress $ protocolInformation $ orclDBSchemaIdentifier $ orclResourceIdentifier ) ) +objectclasses: ( 2.16.840.1.113894.7.2.1001 NAME 'orclService' SUP 'top' STRUCTURAL MUST ( cn ) MAY ( orclServiceType $ orclOracleHome $ orclSystemName $ orclSid $ orclNetDescName $ orclNetDescString $ orclVersion $ Description ) ) +objectclasses: ( 2.16.840.1.113894.2.2.1 NAME 'orclDBServer' SUP 'orclService' STRUCTURAL MAY ( userCertificate $ orclDBtrustedUser $ orclDBGlobalName ) ) +objectClasses: ( 2.16.840.1.113894.3.2.1 NAME 'orclNetAddress' SUP top MUST cn MAY ( orclNetAddressString $ orclNetProtocol $ orclNetShared $ orclVersion $ Description ) ) +objectclasses: ( 2.16.840.1.113894.3.2.8 NAME 'orclNetAddressAux1' SUP top AUXILIARY MAY orclNetHostname ) +objectclasses: ( 2.16.840.1.113894.3.2.2 NAME 'orclNetAddressList' SUP top MUST cn MAY ( orclNetAddrList $ orclNetSourceRoute $ orclNetLoadBalance $ orclNetFailover $ orclNetShared $ orclVersion $ Description ) ) +objectClasses: ( 2.16.840.1.113894.3.2.3 NAME 'orclNetDescription' SUP top MUST cn MAY ( orclNetAddrList $ orclNetProtocolStack $ orclNetSdu $ orclSid $ orclNetServer $ orclNetServiceName $ orclNetInstanceName $ orclNetHandlerName $ orclOracleHome $ orclNetAuthenticationType $ orclNetAuthenticationService $ orclNetAuthParams $ orclNetParamList $ orclNetConnParamList $ orclNetSourceRoute $ orclNetLoadBalance $ orclNetFailover $ orclNetShared $ orclVersion $ Description ) ) +objectClasses: ( 2.16.840.1.113894.3.2.7 NAME 'orclNetDescriptionAux1' SUP top AUXILIARY MAY ( orclNetSendBufSize $ orclNetReceiveBufSize $ orclNetFailoverModeString $ orclNetInstanceRole ) ) +objectclasses: ( 2.16.840.1.113894.3.2.4 NAME 'orclNetDescriptionList' SUP top MUST cn MAY ( orclNetDescList $ orclNetSourceRoute $ orclNetLoadBalance $ orclNetFailover $ orclNetShared $ orclVersion $ Description ) ) +objectclasses: ( 2.16.840.1.113894.3.2.5 NAME 'orclNetService' SUP top MUST cn MAY ( orclNetDescName $ orclNetDescString $ orclVersion $ Description ) ) +objectclasses: ( 2.16.840.1.113894.3.2.6 NAME 'orclNetServiceAlias' SUP alias MUST cn ) \ No newline at end of file diff --git a/ldif/ACI.ldif_template b/ldif/ACI.ldif_template new file mode 100644 index 0000000..b46100c --- /dev/null +++ b/ldif/ACI.ldif_template @@ -0,0 +1,29 @@ +# ---------------------------------------------------------------------------- +# Trivadis - Part of Accenture, Platform Factory - Transactional Data Platform +# Saegereistrasse 29, 8152 Glattbrugg, Switzerland +# ---------------------------------------------------------------------------- +# Name.......: ACI.ldif +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2021.12.07 +# Revision...: -- +# Purpose....: LDAP modify ACI for oracle names +# Notes......: +# Reference..: +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# Modified...: +# see git revision history with git log for more information on changes +# ---------------------------------------------------------------------------- +dn: +changetype: modify +add: aci +aci: (targetattr!="userPassword||authPassword")(version 3.0; acl "Anonymous read access"; allow (read,search,compare) userdn="ldap:///anyone";) + +dn: +changetype: modify +add: aci +aci: (targetattr!="userPassword||authPassword")(version 3.0; acl "TNS Admin access"; allow (all) groupdn="ldap:///cn=TNS Admins,ou=Groups,";) + +# --- EOF -------------------------------------------------------------------- \ No newline at end of file diff --git a/ldif/OracleContext.ldif_template b/ldif/OracleContext.ldif_template new file mode 100644 index 0000000..779faca --- /dev/null +++ b/ldif/OracleContext.ldif_template @@ -0,0 +1,20 @@ +# ---------------------------------------------------------------------------- +# Name.......: OracleContext.ldif +# Author.....: Stefan Oehrli (oes) stefan.oehrli@trivadis.com +# Editor.....: Stefan Oehrli +# Date.......: 2021.12.07 +# Revision...: -- +# Purpose....: LDAP Add Oracle Context +# Notes......: +# Reference..: +# License....: Apache License Version 2.0, January 2004 as shown +# at http://www.apache.org/licenses/ +# ---------------------------------------------------------------------------- +# Modified...: +# see git revision history with git log for more information on changes +# ---------------------------------------------------------------------------- +dn: cn=OracleContext, +objectclass: orclContext +cn: OracleContext + +# --- EOF -------------------------------------------------------------------- \ No newline at end of file diff --git a/ldif/README.md b/ldif/README.md new file mode 100644 index 0000000..6a68695 --- /dev/null +++ b/ldif/README.md @@ -0,0 +1,12 @@ +# LDIF Data Files + +This folder contains various *LDIF* data files used to initialize and configure +the OpenLDAP directory server. In particular the Oracle TNS schema, basis data +and more. + +- [90orclNet.ldif](./90orclNet.ldif) *LDAP* schema definition for *Oracle Context* + required to store *Oracle Net Service* objects in *LDAP*. +- [ACI.ldif_template](./ACI.ldif_template) *LDIF* template to define the ACIs for + anonymous access of the *Oracle Net Service* objects. +- [OracleContext.ldif_template](./OracleContext.ldif_template) *LDIF* template + for a basic *Oracle Context* used to store *Oracle Net Service* objects. diff --git a/log/README.md b/log/README.md new file mode 100644 index 0000000..6d82d27 --- /dev/null +++ b/log/README.md @@ -0,0 +1,4 @@ +# Log Files + +This folder contains various Log files generated by the scripts, if they not +stored in *LOG_BASE*.