Files
Guillaume BOURGEOIS 07fe4b50a7 feat(active-directory): LDAP directory administration integration
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>
2026-06-26 17:22:22 +02:00

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: {} }