Manage 389 Directory Server Data with dsidm

dsidm manages directory data in a 389 Directory Server instance — organizational units, POSIX users and groups, groupOfNames, service accounts, roles, and client configuration snippets. Server tuning stays in dsconf; instance control stays in dsctl.

Published

Updated

Read time 12 min read

Reviewed byDeepak Prasad

Manage 389 Directory Server Data with dsidm
About dsidm manages directory data in a 389 Directory Server instance — organizational units, POSIX users and groups, groupOfNames, service accounts, roles, and client configuration snippets. Server tuning stays in dsconf; instance control stays in dsctl.
Tested on Rocky Linux 10.2; 389 Directory Server 3.2.0; instance ldap1; suffix dc=example,dc=com
Package 389-ds-base (apt/deb) · 389-ds-base (dnf/rpm)
Man page dsidm(8)
Privilege root for local LDAPI autobind, or an LDAP identity with suitable data ACIs
Distros

RHEL, Rocky Linux, AlmaLinux, Fedora: 389-ds-base.

Debian and Ubuntu: 389-ds-base. The optional 389-ds metapackage can install additional administration components.

Related guide

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; suffix dc=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.

bash
dsidm -b dc=example,dc=com ldap1 user list

dsidm — 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:

text
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:

text
<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.

bash
dsidm ldap1 ou create --ou People

Sample output:

output
Successfully created People
bash
dsidm ldap1 ou create --ou Groups
bash
dsidm ldap1 ou create --ou Services

List what exists:

bash
dsidm ldap1 ou list

Sample output:

output
People
Groups
Services

These 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.

bash
dsidm ldap1 user create --uid demo1 --cn "Demo User" --displayName "Demo User" --uidNumber 21001 --gidNumber 21001 --homeDirectory /home/demo1

Sample output:

output
Successfully created demo1

Verify the entry:

bash
dsidm ldap1 user get demo1

Sample output:

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: 21001

objectClass 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.

bash
dsidm ldap1 user modify demo1 replace:mail:[email protected]

Sample output:

output
Successfully modified uid=demo1,ou=people,dc=example,dc=com

Confirm the attribute:

bash
dsidm ldap1 user get demo1

The 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.

bash
dsidm ldap1 group create --cn demogrp --description "Demo group"

Sample output:

output
Successfully created demogrp

Add a member by full DN (note ou=people matches where user create placed the account):

bash
dsidm ldap1 group add_member demogrp uid=demo1,ou=people,dc=example,dc=com

Sample output:

output
added member: uid=demo1,ou=people,dc=example,dc=com

List members:

bash
dsidm ldap1 group members demogrp

Sample output:

output
dn: uid=demo1,ou=people,dc=example,dc=com
Common 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.

bash
dsidm ldap1 account entry-status uid=demo1,ou=people,dc=example,dc=com

Sample output:

output
Entry DN: uid=demo1,ou=people,dc=example,dc=com
Entry State: activated

Lock the account:

bash
dsidm ldap1 account lock uid=demo1,ou=people,dc=example,dc=com

Sample output:

output
Entry uid=demo1,ou=people,dc=example,dc=com is locked

Unlock when the incident is resolved:

bash
dsidm ldap1 account unlock uid=demo1,ou=people,dc=example,dc=com
Advanced 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.

bash
dsidm ldap1 posixgroup create --cn labadmins --gidNumber 21002

Sample output:

output
Successfully created labadmins
bash
dsidm ldap1 service create --cn myapp --description "Application bind account"

List service entries:

bash
dsidm ldap1 service list

Sample output:

output
myapp

Set 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.

bash
dsidm ldap1 client_config display

Sample output (trimmed):

output
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 = rfc2307

Generate an OpenLDAP ldap.conf fragment:

bash
dsidm ldap1 client_config ldap.conf

Sample output (trimmed):

output
BASE    dc=example,dc=com
URI     ldapi://%2fvar%2frun%2fslapd-ldap1.socket

Treat 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).

bash
dsidm ldap1 user rename demo1 demobob

Sample output:

output
Successfully renamed to uid=demobob,ou=people,dc=example,dc=com

Look up by the new uid:

bash
dsidm ldap1 user get demobob

Group 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.

bash
dsidm -j ldap1 user list

Sample output:

output
{
    "type": "list",
    "items": [
        "demobob"
    ]
}

dsidm — when to use / when not

Use dsidm when Use something else when
  • You are creating OUs, POSIX users, groups, or service accounts in the DIT
  • You need lock/unlock, password reset, or account status for entries
  • You want opinionated object classes without writing LDIF by hand
  • You are generating ldap.conf or sssd.conf starter snippets
  • You select groups by cn and manage members using their full DNs
  • Changing listeners, indexes, replication, or plug-ins → dsconf
  • Stopping the server or offline LDIF export → dsctl
  • Add a set of new entries while preserving existing data → ldapadd
  • Replace or repopulate an entire backend from LDIF → dsconf backend import; take a tested backup first — see import and export LDIF
  • Arbitrary entry types outside dsidm helpers → ldapmodify

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.


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

Rohan Timalsina

is a technical writer and Linux enthusiast who writes practical guides on Linux commands and system administration. He focuses on simplifying complex topics through clear explanations.