diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml new file mode 100644 index 0000000..6f15b22 --- /dev/null +++ b/.github/workflows/linting.yml @@ -0,0 +1,11 @@ +name: Linting +on: [push, pull_request] +jobs: + lint: + # Run per push for internal contributers. This isn't possible for forked pull requests, + # so we'll need to run on PR events for external contributers. + # String comparison below is case insensitive. + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + runs-on: ubuntu-latest + steps: + - uses: 'phantomcyber/dev-cicd-tools/github-actions/lint@main' diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 0000000..23d31c5 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,28 @@ +name: Semgrep +on: + pull_request_target: + branches: + - next + - main + push: + branches: + - next + - main +jobs: + semgrep: + runs-on: ubuntu-latest + steps: + - if: github.event_name == 'push' + run: | + echo "REPOSITORY=${{ github.repository }}" >> $GITHUB_ENV + echo "REF=${{ github.REF }}" >> $GITHUB_ENV + - if: github.event_name == 'pull_request_target' + run: | + echo "REPOSITORY=${{ github.event.pull_request.head.repo.full_name }}" >> $GITHUB_ENV + echo "REF=${{ github.event.pull_request.head.ref }}" >> $GITHUB_ENV + - uses: 'phantomcyber/dev-cicd-tools/github-actions/semgrep@main' + with: + SEMGREP_DEPLOYMENT_ID: ${{ secrets.SEMGREP_DEPLOYMENT_ID }} + SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} + REPOSITORY: ${{ github.repository }} + REF: ${{ github.ref }} diff --git a/.github/workflows/start-release.yml b/.github/workflows/start-release.yml new file mode 100644 index 0000000..d5fb354 --- /dev/null +++ b/.github/workflows/start-release.yml @@ -0,0 +1,9 @@ +name: Start Release +on: workflow_dispatch +jobs: + start-release: + runs-on: ubuntu-latest + steps: + - uses: 'phantomcyber/dev-cicd-tools/github-actions/start-release@main' + with: + GITHUB_TOKEN: ${{ secrets.SOAR_APPS_TOKEN }} \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..909f402 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +repos: +- repo: https://github.com/phantomcyber/dev-cicd-tools + rev: v1.4 + hooks: + - id: org-hook + - id: package-app-dependencies +- repo: https://github.com/Yelp/detect-secrets + rev: v1.1.0 + hooks: + - id: detect-secrets + args: ['--no-verify', '--exclude-files', '^adldap.json$'] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b3cc507 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,2 @@ +# Contributing +For more information about contributing to Splunk SOAR Apps please take a look at our app [Contribution Guide](https://github.com/splunk-soar-connectors/.github/blob/main/.github/CONTRIBUTING.md)! diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8fd58df --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + 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 2021-2022 Splunk Inc. + + 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/NOTICE b/NOTICE new file mode 100644 index 0000000..aae176f --- /dev/null +++ b/NOTICE @@ -0,0 +1,19 @@ +Splunk SOAR AD LDAP +Copyright (c) 2021-2022 Splunk Inc. + +Third-party Software Attributions: + +Library: ldap3 +Version: 2.6.1 +License: LGPL 3.0 +Copyright 2013-2018 Giovanni Cannata + +Library: pyasn1 +Version: 0.4.7 +License: BSD 2 +Copyright 2005-2019 Ilya Etingof + +Library: requests +Version: 2.25.0 +License: Apache 2.0 +Kenneth Reitz diff --git a/README.md b/README.md new file mode 100644 index 0000000..304e31e --- /dev/null +++ b/README.md @@ -0,0 +1,426 @@ +[comment]: # "Auto-generated SOAR connector documentation" +# AD LDAP + +Publisher: Splunk +Connector Version: 2\.0\.6 +Product Vendor: Splunk +Product Name: Active Directory LDAP +Product Version Supported (regex): "\.\*" +Minimum Product Version: 4\.9\.39220 + +App specifically designed for interacting with Microsoft Active Directory's LDAP Implementation + +[comment]: # " File: readme.md" +[comment]: # " Copyright (c) 2021 Splunk Inc." +[comment]: # "" +[comment]: # " Licensed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0.txt)" +[comment]: # "" +## App Information + +- This LDAP application utilizes the LDAP3 library for Python. This was chosen, in part, due to + the pythonic design of the library and the quality of the documentation. Both SSL and TLS are + supported. +- Please make sure to view additional documentation for this app on our [GitHub Open Source + Repo!](https://github.com/phantomcyber/phantom-apps/tree/next/Apps/phadldap#readme) + +## LDAP Ports Requirements (Based on Standard Guidelines of [IANA ORG](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml) ) + +- LDAP(service) TCP(transport protocol) - 389 +- LDAP(service) UDP(transport protocol) - 389 +- LDAP(service) TCP(transport protocol) over TLS/SSL (was sldap) - 636 +- LDAP(service) UDP(transport protocol) over TLS/SSL (was sldap) - 636 + +## Asset Configuration + +The asset for this app requires an account with which to Bind and perform actions. If you are only +ever going to perform information gathering tasks (e.g. getting account attributes) then a standard +user account would be fine. However, if you plan on doing things like Unlocking, Resetting +Passwords, Moving objects, etc. - then you will need an account with permissions to actually perform +these actions. It is best practice to NOT use a "Domain Administrator" (or higher) account. Instead, +delegate the appropriate least-privilege access to a service account with a very strong password. +Lastly, it is strongly recommended to use SSL and disallow insecure (plain text and unsigned binds) +if at all possible. + +## Run Query Action + +This action provides the user the ability to run generic queries with the LDAP syntax. The action +takes a filter (in LDAP syntax), an optional search base to search within, and specific attributes +that you would like to return. + +- Common AD LDAP Run Query Examples + + + + - Get Users belonging to a specific OU, Container, or Group + + + + - filter = (samaccountname=\*) + - attributes = samaccountname;mail + - search_base = distinguishedNameOfOU/Container/Group + + - List Group Names that a User belongs to + + + + - filter = (&(member=distinguishedNameOfUserHERE)(objectClass=group)) + - attributes = name + + - Return results if mail attribute is present OR sAMAccountName matches '\*admin\*' + + + + - filter = (\|(mail=\*)(samaccountname=\*admin\*)) + - attributes = samaccountname;mail;userprincipalname;distinguishedname + + - If you would like to learn more about LDAP Filter Syntax, check out this [Microsoft + Wiki](https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx) + + + + +### Configuration Variables +The below configuration variables are required for this Connector to operate. These variables are specified when configuring a Active Directory LDAP asset in SOAR. + +VARIABLE | REQUIRED | TYPE | DESCRIPTION +-------- | -------- | ---- | ----------- +**server** | required | string | The Active Directory Server hostname, IP, or VIP for binding +**username** | required | string | The username with which to bind to LDAP +**password** | required | password | The password for the binding user +**force\_ssl** | required | boolean | Force the use of SSL protocol\. Note that some actions are not possible without secure binding\! +**validate\_ssl\_cert** | required | boolean | Select if you want to validate the LDAP SSL certificate +**ssl\_port** | required | numeric | The port to bind for SSL \(default 636\) + +### Supported Actions +[test connectivity](#action-test-connectivity) - Validate the asset configuration for connectivity using supplied configuration +[add group members](#action-add-group-members) - Adds one or more Active Directory objects to one or more groups +[remove group members](#action-remove-group-members) - Removes one or more Active Directory objects from one or more groups +[unlock account](#action-unlock-account) - Unlocks a locked Active Directory account +[disable account](#action-disable-account) - Disables an Active Directory account +[enable account](#action-enable-account) - Enables a disabled Active Directory account +[reset password](#action-reset-password) - Resets the password of a user, requiring the user to change password at next login +[set password](#action-set-password) - Set a user's password +[move object](#action-move-object) - Moves an entry in Active Directory +[run query](#action-run-query) - Query Active Directory LDAP +[get attributes](#action-get-attributes) - Get attributes of various principals +[set attribute](#action-set-attribute) - Add, delete, or replace an attribute of a user + +## action: 'test connectivity' +Validate the asset configuration for connectivity using supplied configuration + +Type: **test** +Read only: **True** + +#### Action Parameters +No parameters are required for this action + +#### Action Output +No Output + +## action: 'add group members' +Adds one or more Active Directory objects to one or more groups + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**use\_samaccountname** | optional | Specify members AND groups as sAMAccountName\(s\) instead of distinguishedName\(s\) \(note\: member AND groups will use sAMAccountName if selected\) | boolean | +**members** | required | Semi\-colon \(';'\) separated list of users\. If 'use samaccountname' is false, then these must be distinguishedName\(s\) | string | +**groups** | required | Semi\-colon \(';'\) separated list of groups to which the members will be added\. If 'use samaccountname' is false, then these must be distinguishedName\(s\) | string | + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.data\.\*\.member | string | +action\_result\.data\.\*\.function | string | +action\_result\.data\.\*\.group | string | +action\_result\.summary | string | +action\_result\.status | string | +action\_result\.message | string | +action\_result\.parameter\.use\_samaccountname | string | +action\_result\.parameter\.members | string | +action\_result\.parameter\.groups | string | +action\_result\.summary\.found\_user\_records | numeric | +action\_result\.summary\.requested\_user\_records | numeric | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'remove group members' +Removes one or more Active Directory objects from one or more groups + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**use\_samaccountname** | optional | Specify members AND groups as sAMAccountName\(s\) instead of distinguishedName\(s\) | boolean | +**members** | required | Semi\-colon \(';'\) separated list of users\. If 'use samaccountname' is false, then these must be distinguishedName\(s\) | string | +**groups** | required | Semi\-colon \(';'\) separated list of groups from which the members will be removed\. If 'use samaccountname' is false, then these must be distinguishedName\(s\) | string | + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.data\.\*\.member | string | +action\_result\.data\.\*\.function | string | +action\_result\.data\.\*\.group | string | +action\_result\.summary | string | +action\_result\.status | string | +action\_result\.message | string | +action\_result\.parameter\.use\_samaccountname | string | +action\_result\.parameter\.members | string | +action\_result\.parameter\.groups | string | +action\_result\.summary\.found\_user\_records | numeric | +action\_result\.summary\.requested\_user\_records | numeric | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'unlock account' +Unlocks a locked Active Directory account + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**use\_samaccountname** | optional | Use sAMAccountName for user instead of distinguishedName\(s\) | boolean | +**user** | required | Specify the user to unlock\. If 'use samaccountname' is false, then this must be the user's distinguishedName | string | `user name` + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.data\.\*\.user\_dn | string | +action\_result\.data\.\*\.samaccountname | string | +action\_result\.data\.\*\.unlocked | boolean | +action\_result\.message | string | +action\_result\.status | string | +action\_result\.parameter\.use\_samaccountname | boolean | +action\_result\.summary | string | +action\_result\.parameter\.user | string | `user name` +action\_result\.summary\.unlocked | numeric | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'disable account' +Disables an Active Directory account + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**use\_samaccountname** | optional | Specify sAMAccountName instead of distinguishedName | boolean | +**user** | required | Specify the user to disable\. If 'use samaccountname' is false, then this must be the user's distinguishedName | string | `user name` + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.parameter\.user | string | `user name` +action\_result\.data\.\*\.starting\_status | string | +action\_result\.summary\.account\_status | string | +action\_result\.status | string | +action\_result\.parameter\.use\_samaccountname | boolean | +action\_result\.message | string | +action\_result\.data\.\*\.user\_dn | string | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'enable account' +Enables a disabled Active Directory account + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**use\_samaccountname** | optional | Specify sAMAccountName instead of distinguishedName | boolean | +**user** | required | Specify the user to enable\. If 'use samaccountname' is false, then this must be the user's distinguishedName | string | `user name` + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.parameter\.user | string | `user name` +action\_result\.data\.\*\.starting\_status | string | +action\_result\.summary\.account\_status | string | +action\_result\.status | string | +action\_result\.parameter\.use\_samaccountname | boolean | +action\_result\.message | string | +action\_result\.data\.\*\.user\_dn | string | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'reset password' +Resets the password of a user, requiring the user to change password at next login + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**use\_samaccountname** | optional | Use sAMAccountName instead of distinguishedName | boolean | +**user** | required | User whose attributes are to be modified | string | `user name` + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.data\.\*\.reset | numeric | +action\_result\.data\.\*\.user\_dn | string | +action\_result\.data\.\*\.samaccountname | string | +action\_result\.status | string | +action\_result\.message | string | +action\_result\.summary\.reset | numeric | +action\_result\.parameter\.user | string | `user name` +action\_result\.parameter\.use\_samaccountname | numeric | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'set password' +Set a user's password + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**use\_samaccountname** | optional | Specify sAMAccountName instead of distinguishedName | boolean | +**user** | required | Specify the user whose password will be set\. If 'use samaccountname' is false, then this must be the user's distinguishedName | string | `user name` +**password** | required | New password | string | +**confirm\_password** | required | Re\-type the password | string | + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.parameter\.user | string | `user name` +action\_result\.data\.\*\.set | boolean | +action\_result\.data\.\*\.user\_dn | string | +action\_result\.data\.\*\.samaccountname | string | +action\_result\.parameter\.password | string | +action\_result\.parameter\.confirm\_password | string | +action\_result\.status | string | +action\_result\.parameter\.use\_samaccountname | boolean | +action\_result\.summary | string | +action\_result\.message | string | +action\_result\.summary\.set | numeric | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'move object' +Moves an entry in Active Directory + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**object** | required | Specify the distinguishedName to move | string | +**destination\_ou** | required | The distinguishedName of the OU the specified object will move to | string | + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.parameter\.object | string | +action\_result\.parameter\.destination\_ou | string | +action\_result\.summary\.moved | string | +action\_result\.data\.\*\.source\_object | string | +action\_result\.data\.\*\.destination\_container | string | +action\_result\.status | string | +action\_result\.message | string | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'run query' +Query Active Directory LDAP + +Type: **investigate** +Read only: **True** + +This action flexibly supports querying Active Directory using LDAP syntax\. + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**filter** | required | The LDAP filter \(must be in LDAP Syntax\) | string | +**search\_base** | optional | The search base to use in its distinguishedName format\. If not specified, the 'defaultNamingContext' will be used | string | +**attributes** | required | Semi\-colon separated list of attributes to collect \(e\.g\. sAMAccountName;mail\) | string | + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.data\.\*\.entries\.\*\.attributes | string | +action\_result\.parameter\.filter | string | +action\_result\.parameter\.search\_base | string | +action\_result\.parameter\.attributes | string | +action\_result\.status | string | +action\_result\.message | string | +action\_result\.summary\.total\_objects | numeric | +action\_result\.data\.\*\.entries\.\*\.dn | string | +action\_result\.data\.\*\.entries\.\*\.attributes\.samaccountname | string | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'get attributes' +Get attributes of various principals + +Type: **investigate** +Read only: **True** + +This action takes any number of principals \(sAMAccountName, distinguishedName, or userprincipalname\) and returns requested attributes\. Separate with semi\-colon \(';'\)\. + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**principals** | required | The semi\-colon separated principals\. These can be sAMAccountName, userprincipalname, or distinguishedName | string | +**attributes** | required | Semi\-colon separated list of attributes to collect | string | + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.parameter\.principals | string | +action\_result\.parameter\.attributes | string | +action\_result\.status | string | +action\_result\.message | string | +summary\.total\_objects | numeric | +action\_result\.summary | string | +action\_result\.data\.\*\.entries\.\*\.attributes | string | +action\_result\.data\.\*\.entries\.\*\.dn | string | +action\_result\.data\.\*\.entries\.\*\.attributes\.objectGUID | string | +action\_result\.summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | + +## action: 'set attribute' +Add, delete, or replace an attribute of a user + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**use\_samaccountname** | optional | Use sAMAccountName instead of distinguishedName | boolean | +**user** | required | User whose attributes are to be modified | string | `user name` +**attribute** | required | The attribute to modify \(add/delete/replace\) | string | +**value** | optional | Attribute value | string | +**action** | required | Semi\-colon separated list of attributes to collect | string | + +#### Action Output +DATA PATH | TYPE | CONTAINS +--------- | ---- | -------- +action\_result\.data\.\*\.message | string | +action\_result\.status | string | +action\_result\.message | string | +action\_result\.summary\.summary | string | +action\_result\.parameter\.user | string | `user name` +action\_result\.parameter\.value | string | +action\_result\.parameter\.action | string | +action\_result\.parameter\.attribute | string | +action\_result\.parameter\.use\_samaccountname | numeric | +summary\.total\_objects | numeric | +summary\.total\_objects\_successful | numeric | \ No newline at end of file diff --git a/__init__.py b/__init__.py index d00b5d7..a3461fb 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,14 @@ # File: __init__.py -# Copyright (c) 2021 Splunk Inc. # -# Licensed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0.txt) +# Copyright (c) 2021-2022 Splunk Inc. +# +# 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/adldap.json b/adldap.json index b4272d9..d4bec6f 100644 --- a/adldap.json +++ b/adldap.json @@ -9,12 +9,13 @@ "product_name": "Active Directory LDAP", "product_version_regex": ".*", "publisher": "Splunk", - "license": "Copyright (c) 2021 Splunk Inc.", - "app_version": "2.0.4", - "utctime_updated": "2021-06-04T19:14:01.000000Z", + "license": "Copyright (c) 2021-2022 Splunk Inc.", + "app_version": "2.0.7", + "utctime_updated": "2022-01-07T04:07:18.000000Z", "package_name": "phantom_adldap", "main_module": "adldap_connector.py", "min_phantom_version": "4.9.39220", + "fips_compliant": true, "app_wizard_version": "1.0.2", "python_version": "3", "latest_tested_versions": [ @@ -22,6 +23,18 @@ ], "pip_dependencies": { "wheel": [ + { + "module": "certifi", + "input_file": "wheels/certifi-2021.10.8-py2.py3-none-any.whl" + }, + { + "module": "chardet", + "input_file": "wheels/chardet-3.0.4-py2.py3-none-any.whl" + }, + { + "module": "idna", + "input_file": "wheels/idna-2.10-py2.py3-none-any.whl" + }, { "module": "ldap3", "input_file": "wheels/ldap3-2.6.1-py2.py3-none-any.whl" @@ -29,6 +42,14 @@ { "module": "pyasn1", "input_file": "wheels/pyasn1-0.4.7-py2.py3-none-any.whl" + }, + { + "module": "requests", + "input_file": "wheels/requests-2.25.0-py2.py3-none-any.whl" + }, + { + "module": "urllib3", + "input_file": "wheels/urllib3-1.26.7-py2.py3-none-any.whl" } ] }, diff --git a/adldap_connector.py b/adldap_connector.py index d467b94..a95353b 100644 --- a/adldap_connector.py +++ b/adldap_connector.py @@ -1,26 +1,37 @@ # File: adldap_connector.py -# Copyright (c) 2021 Splunk Inc. # -# Licensed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0.txt) - - +# Copyright (c) 2021-2022 Splunk Inc. +# +# 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. +# +# # Phantom App imports -import phantom.app as phantom -# import json -from phantom.base_connector import BaseConnector -from phantom.action_result import ActionResult +import json +import os +import ssl # switched from python-ldap to ldap3 for this app. -gsh import ldap3 import ldap3.extend.microsoft.addMembersToGroups import ldap3.extend.microsoft.removeMembersFromGroups import ldap3.extend.microsoft.unlockAccount +import phantom.app as phantom +from ldap3 import Tls from ldap3.core.exceptions import LDAPSocketOpenError from ldap3.utils.dn import parse_dn -from ldap3 import Tls -import ssl -import json -import os +from phantom.action_result import ActionResult +# import json +from phantom.base_connector import BaseConnector + # from adldap_consts import * @@ -241,7 +252,8 @@ def _handle_group_members(self, param, add): ) except Exception as e: if type(e).__name__ == "LDAPInvalidDnError": - error_msg = "LDAPInvalidDnError: If 'use samaccountname' is unchecked, member(s) and group(s) values must be in distinguishedName format" + error_msg = "LDAPInvalidDnError: If 'use samaccountname' is unchecked, member(s) and " \ + "group(s) values must be in distinguishedName format" else: error_msg = str(e) return RetVal( @@ -788,8 +800,9 @@ def finalize(self): if __name__ == '__main__': - import pudb import argparse + + import pudb import requests pudb.set_trace() diff --git a/adldap_view.py b/adldap_view.py index 10b8162..8f635a0 100644 --- a/adldap_view.py +++ b/adldap_view.py @@ -1,9 +1,17 @@ # File: adldap_view.py -# Copyright (c) 2021 Splunk Inc. # -# Licensed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0.txt) - - +# Copyright (c) 2021-2022 Splunk Inc. +# +# 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. def get_ctx_result(result): ctx_result = {} param = result.get_param() diff --git a/display_attributes.html b/display_attributes.html index e5a51c5..5f25648 100644 --- a/display_attributes.html +++ b/display_attributes.html @@ -10,8 +10,17 @@ {% block widget_content %}