07fe4b50a7
Active Directory over LDAP/LDAPS via the ldap3 library, designed to run on a remote engine inside the AD network. 24 commands: raw search, get user/computer/group-members (with userAccountControl decoding), enable/disable/ unlock accounts, set/expire password, password-never-expire, add/remove group membership, move user/computer OU, create/update/delete user/contact/group, and credential testing. Scripts share an ldap3 connection helper that handles SSL/LDAPS/Start TLS, NTLM bind, certificate trust and paged search. ldap3 is imported defensively: if it is missing on the engine host the command returns a clear "pip install ldap3" message instead of crashing. No ingestion source, so no OCSF mapper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
349 lines
18 KiB
YAML
349 lines
18 KiB
YAML
id: active_directory
|
|
name: Active Directory
|
|
version: 1.0.0
|
|
description: "Active Directory over LDAP/LDAPS — query and manage users, computers, groups and contacts (search, enable/disable/unlock, set/expire password, group membership, OU moves, create/update/delete). Runs on a remote engine inside the AD network. Requires the Python 'ldap3' library on the engine host (pip install ldap3)."
|
|
changelog: "1.0.0 — Initial release: full directory administration over LDAP (search, get user/computer/group-members, create/update/delete user/contact/group, enable/disable/unlock, set/expire password, password-never-expire, add/remove group membership, move user/computer OU, test credentials)."
|
|
category: identity
|
|
|
|
# Per-instance configuration. The integration binds to a Domain Controller over
|
|
# LDAP (389) or LDAPS (636). Secure connection (SSL/Start TLS) is required for
|
|
# password operations. Run this integration on a remote engine that can reach the
|
|
# Domain Controller. The bundled scripts require the Python 'ldap3' library to be
|
|
# installed on the engine host: pip install ldap3
|
|
config_schema:
|
|
properties:
|
|
server_ip:
|
|
type: string
|
|
description: "Domain Controller host or IP (e.g. dc01.company.com or 192.168.0.1)"
|
|
port:
|
|
type: string
|
|
description: "LDAP port. Default 389 for LDAP / Start TLS, 636 for LDAPS."
|
|
username:
|
|
type: string
|
|
description: "Bind username (e.g. DOMAIN\\\\user or user@company.com)"
|
|
password:
|
|
type: string
|
|
description: "Bind password"
|
|
x-soar-sensitive: true
|
|
base_dn:
|
|
type: string
|
|
description: "Base DN (e.g. dc=company,dc=com)"
|
|
secure_connection:
|
|
type: string
|
|
description: "Connection security: None, SSL (LDAPS), TLS, or Start TLS. Password operations require SSL or TLS."
|
|
default: SSL
|
|
ssl_version:
|
|
type: string
|
|
description: "SSL/TLS protocol: None, TLS, TLSv1, TLSv1_1, TLSv1_2, or TLS_CLIENT. Default None (let the library negotiate)."
|
|
default: None
|
|
ntlm:
|
|
type: boolean
|
|
description: "Use NTLM authentication for the bind"
|
|
default: false
|
|
unsecure:
|
|
type: boolean
|
|
description: "Trust any TLS certificate (not secure)"
|
|
default: false
|
|
page_size:
|
|
type: string
|
|
description: "LDAP paging size for searches"
|
|
default: "500"
|
|
default_base_query:
|
|
type: string
|
|
description: "Default LDAP filter used by ad-get-user when no query argument is given"
|
|
default: "(&(objectClass=User)(objectCategory=person))"
|
|
required:
|
|
- server_ip
|
|
- username
|
|
- password
|
|
- base_dn
|
|
|
|
commands:
|
|
# ── Connectivity ──────────────────────────────────────────────────────────
|
|
- id: test_connection
|
|
name: ad-test-connection
|
|
description: "Bind to the Domain Controller and verify the configured base DN (used by the Test button)."
|
|
risk: read
|
|
inputs_schema:
|
|
properties: {}
|
|
required: []
|
|
outputs_schema: { properties: {} }
|
|
|
|
# ── Search / read ─────────────────────────────────────────────────────────
|
|
- id: ad_search
|
|
name: ad-search
|
|
description: "Run a raw LDAP query and return the matching entries. Paging is handled internally up to size-limit."
|
|
risk: read
|
|
inputs_schema:
|
|
properties:
|
|
filter: { type: string, description: "LDAP search filter, e.g. (&(objectCategory=person)(objectClass=user))" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
attributes: { type: string, description: "CSV list of attributes to return, or ALL for every attribute" }
|
|
size-limit: { type: number, description: "Maximum entries to return (default 50)" }
|
|
time-limit: { type: number, description: "Maximum search time in seconds" }
|
|
page-size: { type: number, description: "Paging size (overrides size-limit when set)" }
|
|
required: [filter]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_get_user
|
|
name: ad-get-user
|
|
description: "Retrieve user accounts by DN, name, email, sAMAccountName or a custom attribute. Decodes userAccountControl flags."
|
|
risk: read
|
|
inputs_schema:
|
|
properties:
|
|
dn: { type: string, description: "Distinguished Name of the user" }
|
|
name: { type: string, description: "Common name (cn) of the user" }
|
|
email: { type: string, description: "User email (mail)" }
|
|
username: { type: string, description: "sAMAccountName" }
|
|
sAMAccountName: { type: string, description: "sAMAccountName (alias of username)" }
|
|
custom-field-type: { type: string, description: "Attribute name to query by" }
|
|
custom-field-data: { type: string, description: "Attribute value (required with custom-field-type)" }
|
|
attributes: { type: string, description: "CSV list of extra attributes to add to the defaults" }
|
|
attributes-to-exclude: { type: string, description: "CSV list of attributes to remove from the result" }
|
|
limit: { type: number, description: "Maximum users to return (default 20)" }
|
|
page-size: { type: number, description: "Paging size (overrides limit when set)" }
|
|
required: []
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_get_computer
|
|
name: ad-get-computer
|
|
description: "Retrieve computer accounts by DN, name or a custom attribute."
|
|
risk: read
|
|
inputs_schema:
|
|
properties:
|
|
dn: { type: string, description: "Distinguished Name of the computer" }
|
|
name: { type: string, description: "Computer name" }
|
|
custom-field-type: { type: string, description: "Attribute name to query by" }
|
|
custom-field-data: { type: string, description: "Attribute value (required with custom-field-type)" }
|
|
attributes: { type: string, description: "CSV list of extra attributes to add to the defaults" }
|
|
limit: { type: number, description: "Maximum computers to return" }
|
|
page-size: { type: number, description: "Paging size (overrides limit when set)" }
|
|
required: []
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_get_group_members
|
|
name: ad-get-group-members
|
|
description: "List the users, computers or nested groups that are members of a group (recursive by default)."
|
|
risk: read
|
|
inputs_schema:
|
|
properties:
|
|
group-dn: { type: string, description: "Distinguished Name of the group" }
|
|
member-type: { type: string, description: "Member type to return: person, computer or group (default person)" }
|
|
attributes: { type: string, description: "CSV list of extra attributes to add to the defaults" }
|
|
time_limit: { type: number, description: "Search time limit in seconds (default 180)" }
|
|
disable-nested-search: { type: string, description: "Set true to disable recursive membership resolution (default false)" }
|
|
sAMAccountName: { type: string, description: "Filter members by sAMAccountName (default *)" }
|
|
limit: { type: number, description: "Maximum members to return" }
|
|
page-size: { type: number, description: "Paging size (overrides limit when set)" }
|
|
required: [group-dn]
|
|
outputs_schema: { properties: {} }
|
|
|
|
# ── Account state ─────────────────────────────────────────────────────────
|
|
- id: ad_enable_account
|
|
name: ad-enable-account
|
|
description: "Enable a previously disabled user account."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "sAMAccountName of the account to enable" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
restore_user: { type: string, description: "Set true to restore the account's previous userAccountControl flags" }
|
|
required: [username]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_disable_account
|
|
name: ad-disable-account
|
|
description: "Disable a user account."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "sAMAccountName of the account to disable" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [username]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_unlock_account
|
|
name: ad-unlock-account
|
|
description: "Unlock a locked-out user account."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "sAMAccountName of the account to unlock" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [username]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_set_new_password
|
|
name: ad-set-new-password
|
|
description: "Set a new password for a user. Requires a secure connection (SSL or TLS)."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "sAMAccountName whose password will be set" }
|
|
password: { type: string, description: "New password", x-soar-sensitive: true }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [username, password]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_expire_password
|
|
name: ad-expire-password
|
|
description: "Force a user to change their password at next login."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "sAMAccountName of the user" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [username]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_modify_password_never_expire
|
|
name: ad-modify-password-never-expire
|
|
description: "Set or clear the 'Password Never Expire' flag on a user account."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "sAMAccountName of the user" }
|
|
value: { type: string, description: "true to set 'Password Never Expire', false to clear it" }
|
|
required: [username, value]
|
|
outputs_schema: { properties: {} }
|
|
|
|
# ── Group membership ──────────────────────────────────────────────────────
|
|
- id: ad_add_to_group
|
|
name: ad-add-to-group
|
|
description: "Add a user, computer or nested group to a group."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "Username(s) to add (single or CSV). Mutually exclusive with computer-name." }
|
|
computer-name: { type: string, description: "Computer name(s) to add (single or CSV)" }
|
|
nested_group_cn: { type: string, description: "A group CN to add as a nested member" }
|
|
group-cn: { type: string, description: "Target group CN" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [group-cn]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_remove_from_group
|
|
name: ad-remove-from-group
|
|
description: "Remove a user or computer from a group."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "Username to remove. Mutually exclusive with computer-name." }
|
|
computer-name: { type: string, description: "Computer name to remove" }
|
|
group-cn: { type: string, description: "Target group CN" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [group-cn]
|
|
outputs_schema: { properties: {} }
|
|
|
|
# ── Organizational unit ───────────────────────────────────────────────────
|
|
- id: ad_modify_user_ou
|
|
name: ad-modify-user-ou
|
|
description: "Move a user to a different organizational unit within the domain."
|
|
inputs_schema:
|
|
properties:
|
|
user-name: { type: string, description: "Name of the user to move" }
|
|
full-superior-dn: { type: string, description: "Target OU DN, e.g. OU=users,DC=domain,DC=com" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [user-name, full-superior-dn]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_modify_computer_ou
|
|
name: ad-modify-computer-ou
|
|
description: "Move a computer to a different organizational unit within the domain."
|
|
inputs_schema:
|
|
properties:
|
|
computer-name: { type: string, description: "Name of the computer to move" }
|
|
full-superior-dn: { type: string, description: "Target OU DN, e.g. OU=computers,DC=domain,DC=com" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [computer-name, full-superior-dn]
|
|
outputs_schema: { properties: {} }
|
|
|
|
# ── Object lifecycle: users ───────────────────────────────────────────────
|
|
- id: ad_create_user
|
|
name: ad-create-user
|
|
description: "Create a user account, set its initial password and enable it. Requires a secure connection (SSL or TLS)."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "sAMAccountName for the new user" }
|
|
password: { type: string, description: "Initial password (user must change at next login)", x-soar-sensitive: true }
|
|
user-dn: { type: string, description: "Full DN of the new user" }
|
|
display-name: { type: string, description: "Display name" }
|
|
description: { type: string, description: "Description" }
|
|
email: { type: string, description: "Email (mail)" }
|
|
telephone-number: { type: string, description: "Telephone number" }
|
|
title: { type: string, description: "Job title" }
|
|
custom-attributes: { type: string, description: "JSON object of extra attributes, e.g. {\"company\":\"ACME\"}" }
|
|
required: [username, password, user-dn]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_update_user
|
|
name: ad-update-user
|
|
description: "Replace a single attribute on an existing user."
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "sAMAccountName of the user" }
|
|
attribute-name: { type: string, description: "Attribute to modify (e.g. sn, displayName, mail)" }
|
|
attribute-value: { type: string, description: "New value" }
|
|
base-dn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [username, attribute-name, attribute-value]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_delete_user
|
|
name: ad-delete-user
|
|
description: "Delete a user (or any object) by its DN."
|
|
inputs_schema:
|
|
properties:
|
|
user-dn: { type: string, description: "DN of the object to delete" }
|
|
required: [user-dn]
|
|
outputs_schema: { properties: {} }
|
|
|
|
# ── Object lifecycle: contacts ────────────────────────────────────────────
|
|
- id: ad_create_contact
|
|
name: ad-create-contact
|
|
description: "Create a contact object."
|
|
inputs_schema:
|
|
properties:
|
|
contact-dn: { type: string, description: "Full DN of the new contact" }
|
|
display-name: { type: string, description: "Display name" }
|
|
description: { type: string, description: "Description" }
|
|
email: { type: string, description: "Email (mail)" }
|
|
telephone-number: { type: string, description: "Telephone number" }
|
|
title: { type: string, description: "Job title" }
|
|
custom-attributes: { type: string, description: "JSON object of extra attributes" }
|
|
required: [contact-dn]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_update_contact
|
|
name: ad-update-contact
|
|
description: "Replace a single attribute on an existing contact."
|
|
inputs_schema:
|
|
properties:
|
|
contact-dn: { type: string, description: "DN of the contact" }
|
|
attribute-name: { type: string, description: "Attribute to modify" }
|
|
attribute-value: { type: string, description: "New value" }
|
|
required: [contact-dn, attribute-name, attribute-value]
|
|
outputs_schema: { properties: {} }
|
|
|
|
# ── Object lifecycle: groups ──────────────────────────────────────────────
|
|
- id: ad_create_group
|
|
name: ad-create-group
|
|
description: "Create a security or distribution group."
|
|
inputs_schema:
|
|
properties:
|
|
name: { type: string, description: "Group name (sAMAccountName)" }
|
|
group-type: { type: string, description: "security or distribution" }
|
|
dn: { type: string, description: "Full DN of the new group" }
|
|
members: { type: array, description: "DNs of initial members" }
|
|
required: [name, group-type, dn]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_update_group
|
|
name: ad-update-group
|
|
description: "Replace a single attribute on an existing group."
|
|
inputs_schema:
|
|
properties:
|
|
groupname: { type: string, description: "Group name (cn) to update" }
|
|
attributename: { type: string, description: "Attribute to modify (e.g. description, displayName)" }
|
|
attributevalue: { type: string, description: "New value" }
|
|
basedn: { type: string, description: "Search base (defaults to the instance base_dn)" }
|
|
required: [attributename, attributevalue]
|
|
outputs_schema: { properties: {} }
|
|
- id: ad_delete_group
|
|
name: ad-delete-group
|
|
description: "Delete a security or distribution group by its DN."
|
|
inputs_schema:
|
|
properties:
|
|
dn: { type: string, description: "DN of the group" }
|
|
required: [dn]
|
|
outputs_schema: { properties: {} }
|
|
|
|
# ── Credentials ───────────────────────────────────────────────────────────
|
|
- id: ad_test_credentials
|
|
name: ad-test-credentials
|
|
description: "Test whether a username/password can bind to the Domain Controller."
|
|
risk: read
|
|
inputs_schema:
|
|
properties:
|
|
username: { type: string, description: "Username to test (user or SERVER\\\\user)" }
|
|
password: { type: string, description: "Password to test", x-soar-sensitive: true }
|
|
required: [username, password]
|
|
outputs_schema: { properties: {} }
|