dsidm is the data administration tool for 389 Directory Server. It creates and maintains organizational units, POSIX users, groupOfNames and groupOfUniqueNames groups, POSIX groups, service accounts, and roles — without hand-writing LDIF for common object classes. Plug-in and listener changes stay in dsconf; start/stop belongs to dsctl. This cheat sheet is part of the 389 Directory Server tutorial.
Tested on: Rocky Linux 10.2; 389 Directory Server 3.2.0; instance
ldap1; suffixdc=example,dc=com.
The examples assume that basedn = dc=example,dc=com is configured for ldap1 in .dsrc. Without that setting, add -b dc=example,dc=com before the instance name or enter the base DN when prompted.
dsidm -b dc=example,dc=com ldap1 user listdsidm — quick reference
Connection options
When you pass a local instance name, dsidm normally connects through LDAPI. Root can usually use LDAPI autobind without entering the Directory Manager password. Other local or remote administrators need an LDAP identity with suitable data ACIs.
| When to use | Command |
|---|---|
| Target local instance | dsidm ldap1 COMMAND |
| Target remote server | dsidm ldap://ldap1.example.com:389 COMMAND |
| Bind as Directory Manager | dsidm -D "cn=Directory Manager" -W ldap1 COMMAND |
| Password from file | dsidm -y /root/dm.pw ldap1 COMMAND |
| Default suffix context | dsidm -b dc=example,dc=com ldap1 COMMAND |
| StartTLS | dsidm -Z ldap://host:389 COMMAND |
| JSON output | dsidm -j ldap1 user list |
An ldap:// URL does not encrypt credentials or directory data. Use LDAPS, StartTLS with -Z, or a suitable SASL mechanism for remote administration.
Bootstrap (initialise, organizationalunit)
Create the OU layout before users and groups. By default, user commands work under ou=People, group and POSIX-group commands under ou=Groups, and service commands under ou=Services. The user and group container RDNs can be overridden with people_rdn and groups_rdn in .dsrc; service commands currently expect ou=Services.
| When to use | Command |
|---|---|
| Seed domain OUs and sample entries (if not already present) | dsidm ldap1 initialise |
| Create an organizational unit | dsidm ldap1 ou create --ou People |
| List OUs | dsidm ldap1 ou list |
| Delete an OU (interactive confirm; must be empty) | dsidm ldap1 ou delete "ou=People,dc=example,dc=com" |
POSIX users (user)
| When to use | Command |
|---|---|
Create a POSIX user (supply --displayName to skip prompts) |
dsidm ldap1 user create --uid alice --cn "Alice Example" --displayName "Alice Example" --uidNumber 2001 --gidNumber 2001 --homeDirectory /home/alice |
| List users by uid | dsidm ldap1 user list |
| List full user DNs | dsidm ldap1 user list --full-dn |
| Show one user | dsidm ldap1 user get alice |
| Retrieve a user entry by full DN | dsidm ldap1 user get_dn "uid=alice,ou=people,dc=example,dc=com" |
| Modify attributes | dsidm ldap1 user modify alice replace:mail:[email protected] |
| Rename uid (changes RDN) | dsidm ldap1 user rename alice bob |
| Delete user (interactive confirm) | dsidm ldap1 user delete "uid=bob,ou=people,dc=example,dc=com" |
Groups (group, uniquegroup, posixgroup)
| When to use | Command |
|---|---|
Create groupOfNames group |
dsidm ldap1 group create --cn devs --description "Developers" |
| List groups | dsidm ldap1 group list |
| Add member by DN | dsidm ldap1 group add_member devs uid=alice,ou=people,dc=example,dc=com |
| List member DNs | dsidm ldap1 group members devs |
| Remove member | dsidm ldap1 group remove_member devs uid=alice,ou=people,dc=example,dc=com |
Create groupOfUniqueNames |
dsidm ldap1 uniquegroup create --cn ops |
| Create POSIX group (no members) | dsidm ldap1 posixgroup create --cn admins --gidNumber 2002 |
Accounts, services, and roles
| When to use | Command |
|---|---|
| List bindable accounts | dsidm ldap1 account list |
| Lock an entry | dsidm ldap1 account lock uid=alice,ou=people,dc=example,dc=com |
| Unlock an entry | dsidm ldap1 account unlock uid=alice,ou=people,dc=example,dc=com |
| Entry activation state | dsidm ldap1 account entry-status uid=alice,ou=people,dc=example,dc=com |
| Reset password (admin) | dsidm ldap1 account reset_password uid=alice,ou=people,dc=example,dc=com |
| Create service account | dsidm ldap1 service create --cn myapp --description "App bind DN" |
| List roles | dsidm ldap1 role list |
| Create a managed role | dsidm ldap1 role create-managed <options> |
| Create a filtered role | dsidm ldap1 role create-filtered <options> |
| Create a nested role | dsidm ldap1 role create-nested <options> |
Client configuration helpers
| When to use | Command |
|---|---|
| Show generic LDAP client parameters | dsidm ldap1 client_config display |
Generate ldap.conf snippet |
dsidm ldap1 client_config ldap.conf |
Generate sssd.conf snippet |
dsidm ldap1 client_config sssd.conf |
dsidm — command syntax
Synopsis from dsidm -h on the tested host:
usage: dsidm [-h] [-v] [-j] [-b BASEDN] [-D BINDDN] [-w BINDPW] [-W]
[-y PWDFILE] [-Z]
instance
{account,group,initialise,init,organizationalunit,ou,posixgroup,user,client_config,role,service,uniquegroup}
...modify subcommands across object types share one attribute syntax:
<add|delete|replace>:<attribute>:<value>Multiple modifications can appear on one command line. Deletes (user delete, group delete, …) prompt for Yes I am sure unless you pipe confirmation in automation.
Commands such as get, modify, and rename generally accept the short selector (uid, cn, or ou). In contrast, delete and get_dn expect the complete entry DN. Check the positional argument shown by dsidm INSTANCE OBJECT COMMAND --help.
dsidm — command examples
Essential Create the OU layout before users
user, group, and service subcommands expect parent containers. On a clean suffix from dscreate with sample_entries = no, create them explicitly.
dsidm ldap1 ou create --ou PeopleSample output:
Successfully created Peopledsidm ldap1 ou create --ou Groupsdsidm ldap1 ou create --ou ServicesList what exists:
dsidm ldap1 ou listSample output:
People
Groups
ServicesThese become ou=People,dc=example,dc=com, ou=Groups,…, and ou=Services,… in the DIT. The user create subcommand places new users under ou=people (lowercase) by default — LDAPDN comparisons on this server are case-insensitive, but keep DN casing consistent in scripts.
Essential Create a POSIX user without interactive prompts
If you omit --displayName, user create prompts on the terminal. Pass every required attribute on the command line for scripts.
dsidm ldap1 user create --uid demo1 --cn "Demo User" --displayName "Demo User" --uidNumber 21001 --gidNumber 21001 --homeDirectory /home/demo1Sample output:
Successfully created demo1Verify the entry:
dsidm ldap1 user get demo1Sample output:
dn: uid=demo1,ou=people,dc=example,dc=com
cn: Demo User
displayName: Demo User
gidNumber: 21001
homeDirectory: /home/demo1
objectClass: top
objectClass: nsPerson
objectClass: nsAccount
objectClass: nsOrgPerson
objectClass: posixAccount
uid: demo1
uidNumber: 21001objectClass includes posixAccount so Linux clients and SSSD can map the entry to a local UID.
Common Add or replace attributes on a user
Use the shared modify syntax for mail, telephone numbers, or custom schema attributes your ACIs allow.
dsidm ldap1 user modify demo1 replace:mail:[email protected]Sample output:
Successfully modified uid=demo1,ou=people,dc=example,dc=comConfirm the attribute:
dsidm ldap1 user get demo1The mail line should appear in the output. For multi-valued attributes, use add: instead of replace:.
Common Create a group and add a member
group creates a groupOfNames entry. On the tested 389 DS instance, dsidm can create the group without members and populate the member attribute afterward.
dsidm ldap1 group create --cn demogrp --description "Demo group"Sample output:
Successfully created demogrpAdd a member by full DN (note ou=people matches where user create placed the account):
dsidm ldap1 group add_member demogrp uid=demo1,ou=people,dc=example,dc=comSample output:
added member: uid=demo1,ou=people,dc=example,dc=comList members:
dsidm ldap1 group members demogrpSample output:
dn: uid=demo1,ou=people,dc=example,dc=comCommon Lock and unlock an account
The account subcommand handles lock state and password operations across user-like entries. Locking sets nsAccountLock without deleting the entry.
dsidm ldap1 account entry-status uid=demo1,ou=people,dc=example,dc=comSample output:
Entry DN: uid=demo1,ou=people,dc=example,dc=com
Entry State: activatedLock the account:
dsidm ldap1 account lock uid=demo1,ou=people,dc=example,dc=comSample output:
Entry uid=demo1,ou=people,dc=example,dc=com is lockedUnlock when the incident is resolved:
dsidm ldap1 account unlock uid=demo1,ou=people,dc=example,dc=comAdvanced Create a POSIX group and a service account
POSIX groups carry gidNumber for Linux clients. The posixgroup helper creates an entry with both groupOfNames and posixGroup, retaining DN-based membership while supplying a numeric group ID. Service accounts land under ou=Services.
dsidm ldap1 posixgroup create --cn labadmins --gidNumber 21002Sample output:
Successfully created labadminsdsidm ldap1 service create --cn myapp --description "Application bind account"List service entries:
dsidm ldap1 service listSample output:
myappSet a password on the service DN with account reset_password or your organization's password policy workflow.
Advanced Generate client connection hints
client_config inspects the live server and prints URIs, base DN, and filter templates for applications and SSSD.
dsidm ldap1 client_config displaySample output (trimmed):
ldap_uri = ldapi://%2fvar%2frun%2fslapd-ldap1.socket
basedn = dc=example,dc=com
user_basedn = ou=people,dc=example,dc=com
group_basedn = ou=Groups,dc=example,dc=com
schema_type = rfc2307Generate an OpenLDAP ldap.conf fragment:
dsidm ldap1 client_config ldap.confSample output (trimmed):
BASE dc=example,dc=com
URI ldapi://%2fvar%2frun%2fslapd-ldap1.socketTreat output as a starting point — validate hostnames, TLS paths, and filters before production. The SSSD client chapter walks through a full Linux client.
Advanced Rename a user uid
user rename changes the RDN (uid value) and keeps other attributes. Use when a login name changes, not for moving between OUs (that is a modify of the DN via rename-by-dn on account).
dsidm ldap1 user rename demo1 demobobSample output:
Successfully renamed to uid=demobob,ou=people,dc=example,dc=comLook up by the new uid:
dsidm ldap1 user get demobobGroup memberships that store the full member DN must be updated when the user's DN path changes, unless the Referential Integrity plug-in is enabled and configured to update those references automatically — plan renames during maintenance.
Common JSON output for automation
-j returns structured lists for CMDB sync or Ansible facts.
dsidm -j ldap1 user listSample output:
{
"type": "list",
"items": [
"demobob"
]
}dsidm — when to use / when not
| Use dsidm when | Use something else when |
|---|---|
|
|
dsidm vs ldapmodify
| dsidm | ldapmodify | |
|---|---|---|
| Scope | Opinionated 389 DS object types | Any LDIF change |
| Learning curve | Subcommands per object type | Full LDAP attribute knowledge |
| OU prerequisites | Enforced with clear errors | You must create parents yourself |
| Best for | Day-to-day users and groups | Custom schema, one-off fixes, migrations |
For OpenLDAP-oriented examples, see the ldapmodify cheat sheet — syntax is similar, but object classes and ACIs differ on 389 DS.
Related commands
| Command | One line |
|---|---|
| dsidm | Directory data (this page) |
| dsconf | Server configuration |
| dsctl | Instance lifecycle |
| ldapsearch | Verify entries and membership |
| ldapadd | Add new directory entries from LDIF |
Continue with manage users and groups in the course for workflow context, or the tutorial hub.
dsidm — interview corner
What is dsidm for?
dsidm is the directory data CLI for 389 Directory Server. It wraps common entry types — users, groups, OUs, services, roles — with subcommands that apply the right object classes and attribute sets.
It does not replace dsconf for cn=config and does not start or stop the server.
A strong answer is:
"dsidm manages DIT content — users, groups, OUs, services — with helper subcommands instead of raw LDIF for every change."
Why does group create fail with ou=Groups does not exist?
Group entries are created under ou=Groups,<suffix> by default. If dscreate ran with sample_entries = no, only the domain entry exists until you create OUs.
Run dsidm INSTANCE ou create --ou Groups (and People/Services) first, or use initialise when appropriate.
A strong answer is:
"dsidm expects the Groups OU; create it with ou create or initialise before group create."
Why does user create hang?
When required attributes are missing, user create prompts interactively — notably displayName if you omit --displayName.
In scripts and CI, pass all attributes on the command line.
A strong answer is:
"It is waiting for interactive input — pass --displayName and other required fields to avoid prompts."
When do you use group vs posixgroup?
group creates a groupOfNames entry for DN-based membership.
posixgroup adds posixGroup and a required gidNumber while retaining groupOfNames, which is useful when LDAP clients also need a numeric Linux group ID. The exact membership model still depends on your SSSD/NSS schema configuration.
A strong answer is:
"group creates groupOfNames for member DNs; posixgroup adds posixGroup and gidNumber while keeping groupOfNames for clients that need a Linux group ID."
What is the difference between user and account?
user creates and edits POSIX person entries. account operates on existing bindable entries — lock, unlock, password reset, subtree status — regardless of whether you originally used user create.
Use account for operational tasks on entries that already exist.
A strong answer is:
"user is for creating POSIX users; account is for lock, unlock, and password operations on existing accounts."
How does dsidm delete work?
Delete subcommands expect the complete entry DN, not the short uid or cn selector. They prompt for the exact phrase Yes I am sure. This prevents accidental removal of production users.
In automation you can pipe the confirmation, but prefer ldapdelete with backups for bulk cleanup.
A strong answer is:
"Delete needs the full DN and confirms with 'Yes I am sure' — use user get or user list --full-dn to obtain the DN first."
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
The DN "ou=Groups,..." does not exist |
Missing OU | dsidm INSTANCE ou create --ou Groups |
user create waits at prompt |
Missing --displayName |
Pass --displayName "Full Name" |
Already exists (68) on initialise |
Domain or OUs already created | Use ou create individually or skip init |
Type or value exists (20) on add_member |
User already in group | Expected; verify with group members |
No such object (32) on get_dn |
A UID was passed instead of a full DN, or the DN is incorrect | Use user get UID for a short UID, or obtain full DNs with user list --full-dn |
add_member DN mismatch |
Mixed ou=people vs ou=People |
Use the DN from user get or user list --full-dn; server may be case-insensitive but scripts should match |
Can't contact LDAP server |
Instance stopped | dsctl INSTANCE start |
| Delete does nothing | Confirmation not entered | Type Yes I am sure exactly or use ldapdelete |
client_config reports rfc2307 or unknown unexpectedly |
MemberOf is disabled, its configuration is inaccessible, or the inferred schema does not match your client design | Treat generated output as a starting point; verify the MemberOf state and the schema configured in SSSD |
References
- dsctl, dsconf and dsidm (Port389) — scope of the three administration tools
- Users and groups with dsidm (Port389) — basic dsidm user and group workflow
- Security and access control (Red Hat Directory Server 13) — groups, roles, account policy, and authentication
- dsidm(8) man page — command synopsis and subcommands
