User Manager Guide

Configure user accounts, privileges, and LDAP authentication on OpenBMC.

Table of Contents

  1. Overview
  2. Setup & Configuration
    1. Build-Time Configuration (Yocto)
    2. Configuration Files
    3. Deploying Custom PAM Configuration via Yocto
    4. LDAP Configuration Persistence
    5. Runtime Configuration
  3. Local User Management
    1. Default Users
    2. Create User via Redfish
    3. Create User via D-Bus
    4. Modify User
    5. Delete User
  4. Privilege Roles
    1. Available Roles
    2. Role Permissions
    3. D-Bus Privilege Mapping
  5. IPMI User Management
    1. Configure IPMI Users
    2. IPMI User Privileges
  6. LDAP Configuration
    1. Enable LDAP Authentication
    2. LDAP Role Mapping
    3. D-Bus LDAP Configuration
    4. Test LDAP Connection
  7. Active Directory
    1. Configure AD Authentication
  8. Account Policies
    1. Configure Lockout
    2. Password Policy
  9. Session Management
    1. View Active Sessions
    2. Terminate Session
    3. Session Timeout
  10. Troubleshooting
    1. Login Failures
    2. LDAP Issues
    3. Account Locked
  11. Deep Dive
    1. PAM Integration
    2. LDAP Authentication Flow
    3. Password Hashing
    4. D-Bus Permission Enforcement
    5. Source Code Reference
  12. Examples
  13. References

Overview

OpenBMC user management is handled by phosphor-user-manager, providing local accounts, role-based access control, and LDAP integration.

---
title: User Manager Architecture
---
flowchart TB
    subgraph access["Access Methods"]
        direction TB
        redfish["Redfish API"]
        ipmi["IPMI Users"]
        ssh["SSH Login"]
        webui["WebUI Login"]
    end

    access --> usermgr

    subgraph usermgr["phosphor-user-manager"]
        direction TB
        local["Local Accounts<br/>/etc/passwd"]
        ldap["LDAP/AD Config<br/>nslcd/sssd"]
        priv["Privilege<br/>Management"]
    end

    usermgr --> pam["PAM<br/>(Pluggable Authentication Modules)"]
ASCII-art version (for comparison)
┌─────────────────────────────────────────────────────────────────┐
│                   User Manager Architecture                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │                    Access Methods                           ││
│  │                                                             ││
│  │   ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐    ││
│  │   │ Redfish  │  │  IPMI    │  │   SSH    │  │  WebUI   │    ││
│  │   │ API      │  │  Users   │  │ Login    │  │  Login   │    ││
│  │   └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘    ││
│  └────────┼─────────────┼─────────────┼─────────────┼──────────┘│
│           └─────────────┴──────┬──────┴─────────────┘           │
│                                │                                │
│  ┌─────────────────────────────┴───────────────────────────────┐│
│  │                   phosphor-user-manager                     ││
│  │                                                             ││
│  │   ┌────────────────┐  ┌────────────────┐  ┌──────────────┐  ││
│  │   │ Local Accounts │  │ LDAP/AD Config │  │ Privilege    │  ││
│  │   │ /etc/passwd    │  │ nslcd/sssd     │  │ Management   │  ││
│  │   └────────────────┘  └────────────────┘  └──────────────┘  ││
│  └──────────────────────────┬──────────────────────────────────┘│
│                             │                                   │
│  ┌──────────────────────────┴──────────────────────────────────┐│
│  │                          PAM                                ││
│  │              (Pluggable Authentication Modules)             ││
│  └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘

Setup & Configuration

Build-Time Configuration (Yocto)

# In your machine .conf or local.conf

# Include user management
IMAGE_INSTALL:append = " \
    phosphor-user-manager \
"

# For LDAP support
IMAGE_INSTALL:append = " \
    nss-pam-ldapd \
    pam-plugin-ldap \
"

# Configure Meson options
EXTRA_OEMESON:pn-phosphor-user-manager = " \
    -Dldap=enabled \
"

Configuration Files

Config File Install Path Description
PAM auth config /etc/pam.d/common-auth Authentication module stack
PAM password config /etc/pam.d/common-password Password change rules
PAM account config /etc/pam.d/common-account Account validation
LDAP client config /etc/nslcd.conf nslcd LDAP client settings
LDAP NSS config /etc/nsswitch.conf Name service switch (adds ldap)
D-Bus policy /etc/dbus-1/system.d/phosphor-user-manager.conf D-Bus access control

Deploying Custom PAM Configuration via Yocto

To customize PAM authentication (e.g., add stricter password policies or modify the auth module order), create a bbappend for the pam recipe:

# meta-myplatform/recipes-phosphor/users/phosphor-user-manager/
# └── files/
# │   └── common-auth
# │   └── common-password
# └── phosphor-user-manager_%.bbappend

cat > phosphor-user-manager_%.bbappend << 'EOF'
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += " \
    file://common-auth \
    file://common-password \
"

do_install:append() {
    # Deploy custom PAM configuration
    install -d ${D}${sysconfdir}/pam.d
    install -m 0644 ${WORKDIR}/common-auth ${D}${sysconfdir}/pam.d/
    install -m 0644 ${WORKDIR}/common-password ${D}${sysconfdir}/pam.d/
}
EOF

Example common-auth with lockout policy:

# /etc/pam.d/common-auth
auth required   pam_tally2.so deny=5 unlock_time=300 onerr=fail
auth sufficient pam_unix.so nullok try_first_pass
auth sufficient pam_ldap.so use_first_pass
auth required   pam_deny.so

LDAP Configuration Persistence

LDAP configuration set via Redfish/D-Bus is persisted to:

# LDAP config persistence (managed by phosphor-user-manager)
/var/lib/phosphor-user-manager/ldap.conf

# nslcd runtime config (generated from D-Bus settings)
/etc/nslcd.conf

To bake default LDAP settings into the image:

# meta-myplatform/recipes-phosphor/users/nss-pam-ldapd/
# └── files/
# │   └── nslcd.conf
# └── nss-pam-ldapd_%.bbappend

cat > nss-pam-ldapd_%.bbappend << 'EOF'
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://nslcd.conf"

do_install:append() {
    install -m 0600 ${WORKDIR}/nslcd.conf ${D}${sysconfdir}/
}
EOF

Runtime Configuration

# Check user manager service
systemctl status phosphor-user-manager

# View logs
journalctl -u phosphor-user-manager -f

# User configuration files
cat /etc/passwd
cat /etc/group

# Verify PAM config
cat /etc/pam.d/common-auth

# Verify LDAP client config
cat /etc/nslcd.conf

Local User Management

Default Users

Username Default Password Role
root 0penBmc Administrator

Create User via Redfish

# Create new user
curl -k -u root:0penBmc -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "UserName": "operator1",
        "Password": "SecurePass123!",
        "RoleId": "Operator",
        "Enabled": true
    }' \
    https://localhost/redfish/v1/AccountService/Accounts

Create User via D-Bus

# Create user
busctl call xyz.openbmc_project.User.Manager \
    /xyz/openbmc_project/user \
    xyz.openbmc_project.User.Manager \
    CreateUser ssasbs \
    "newuser" \
    3 "ipmi" "redfish" "ssh" \
    "priv-admin" \
    true

Modify User

# Change password via Redfish
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{"Password": "NewPassword123!"}' \
    https://localhost/redfish/v1/AccountService/Accounts/operator1

# Change role
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{"RoleId": "Administrator"}' \
    https://localhost/redfish/v1/AccountService/Accounts/operator1

# Enable/disable user
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{"Enabled": false}' \
    https://localhost/redfish/v1/AccountService/Accounts/operator1

Delete User

# Via Redfish
curl -k -u root:0penBmc -X DELETE \
    https://localhost/redfish/v1/AccountService/Accounts/operator1

# Via IPMI
ipmitool -I lanplus -H bmc-ip -U root -P 0penBmc user set name 3 ""

Privilege Roles

Available Roles

Role Redfish IPMI Priv Description
Administrator Administrator 4 (admin) Full access
Operator Operator 3 (operator) Operations, no user mgmt
ReadOnly ReadOnly 2 (user) Read-only access
Callback Callback 1 Limited callback access

Role Permissions

# View available roles
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/AccountService/Roles

# Get role details
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/AccountService/Roles/Operator

D-Bus Privilege Mapping

# View user privileges
busctl get-property xyz.openbmc_project.User.Manager \
    /xyz/openbmc_project/user/newuser \
    xyz.openbmc_project.User.Attributes \
    UserPrivilege

IPMI User Management

Configure IPMI Users

# List users
ipmitool user list

# Create user
ipmitool user set name 3 operator1
ipmitool user set password 3 Password123!
ipmitool user priv 3 3 1  # operator privilege, channel 1
ipmitool user enable 3

# Disable user
ipmitool user disable 3

# Delete user
ipmitool user set name 3 ""

IPMI User Privileges

Level Name Description
1 Callback Minimal access
2 User Read sensors, view logs
3 Operator Power control, sensor config
4 Administrator Full access
5 OEM Vendor-specific

LDAP Configuration

Enable LDAP Authentication

# Configure LDAP via Redfish
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{
        "LDAP": {
            "ServiceEnabled": true,
            "ServiceAddresses": ["ldap://ldap.example.com"],
            "Authentication": {
                "AuthenticationType": "UsernameAndPassword",
                "Username": "cn=admin,dc=example,dc=com",
                "Password": "ldappassword"
            },
            "LDAPService": {
                "SearchSettings": {
                    "BaseDistinguishedNames": ["dc=example,dc=com"],
                    "UsernameAttribute": "uid",
                    "GroupsAttribute": "memberOf"
                }
            }
        }
    }' \
    https://localhost/redfish/v1/AccountService

LDAP Role Mapping

# Map LDAP group to role
curl -k -u root:0penBmc -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "RemoteGroup": "cn=admins,ou=groups,dc=example,dc=com",
        "LocalRole": "Administrator"
    }' \
    https://localhost/redfish/v1/AccountService/LDAP/RemoteRoleMapping

D-Bus LDAP Configuration

# Create LDAP config
busctl call xyz.openbmc_project.User.Manager \
    /xyz/openbmc_project/user/ldap \
    xyz.openbmc_project.User.Ldap.Create \
    Create sssssa{ss} \
    "ldap://ldap.example.com" \
    "cn=admin,dc=example,dc=com" \
    "dc=example,dc=com" \
    "uid" \
    "OpenLDAP" \
    0

Test LDAP Connection

# Test authentication
ldapsearch -x -H ldap://ldap.example.com \
    -D "cn=admin,dc=example,dc=com" \
    -w password \
    -b "dc=example,dc=com" \
    "(uid=testuser)"

Active Directory

Configure AD Authentication

# Configure Active Directory
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{
        "ActiveDirectory": {
            "ServiceEnabled": true,
            "ServiceAddresses": ["ldap://ad.example.com"],
            "Authentication": {
                "AuthenticationType": "UsernameAndPassword",
                "Username": "admin@example.com",
                "Password": "adpassword"
            },
            "LDAPService": {
                "SearchSettings": {
                    "BaseDistinguishedNames": ["DC=example,DC=com"],
                    "UsernameAttribute": "sAMAccountName",
                    "GroupsAttribute": "memberOf"
                }
            }
        }
    }' \
    https://localhost/redfish/v1/AccountService

Account Policies

Configure Lockout

# Set account lockout policy
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{
        "AccountLockoutThreshold": 5,
        "AccountLockoutDuration": 300,
        "AccountLockoutCounterResetAfter": 60
    }' \
    https://localhost/redfish/v1/AccountService

Password Policy

# Set minimum password length
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{
        "MinPasswordLength": 12
    }' \
    https://localhost/redfish/v1/AccountService

Session Management

View Active Sessions

# List sessions
curl -k -u root:0penBmc \
    https://localhost/redfish/v1/SessionService/Sessions

Terminate Session

# Delete specific session
curl -k -u root:0penBmc -X DELETE \
    https://localhost/redfish/v1/SessionService/Sessions/session_id

Session Timeout

# Configure session timeout
curl -k -u root:0penBmc -X PATCH \
    -H "Content-Type: application/json" \
    -d '{"SessionTimeout": 1800}' \
    https://localhost/redfish/v1/SessionService

Troubleshooting

Login Failures

# Check PAM logs
journalctl | grep pam

# Check user exists
cat /etc/passwd | grep username

# Verify user enabled
busctl get-property xyz.openbmc_project.User.Manager \
    /xyz/openbmc_project/user/username \
    xyz.openbmc_project.User.Attributes \
    UserEnabled

LDAP Issues

# Check LDAP service
systemctl status nslcd

# Test LDAP bind
ldapwhoami -x -H ldap://ldap.example.com \
    -D "uid=user,dc=example,dc=com" -W

# Check LDAP configuration
busctl introspect xyz.openbmc_project.User.Manager \
    /xyz/openbmc_project/user/ldap

Account Locked

# Check lockout status (via PAM tally)
pam_tally2 --user=username

# Reset lockout
pam_tally2 --user=username --reset

Deep Dive

Advanced implementation details for user management developers.

PAM Integration

OpenBMC uses PAM (Pluggable Authentication Modules) for authentication:

┌─────────────────────────────────────────────────────────────────────────┐
│                    PAM Authentication Flow                              │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   Login Request (Redfish/IPMI/SSH)                                      │
│          │                                                              │
│          ▼                                                              │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │                    PAM Stack                                    │   │
│   │   /etc/pam.d/common-auth                                        │   │
│   └────────────────────────────┬────────────────────────────────────┘   │
│                                │                                        │
│          ┌─────────────────────┼─────────────────────┐                  │
│          │                     │                     │                  │
│          ▼                     ▼                     ▼                  │
│   ┌────────────┐        ┌────────────┐        ┌────────────┐            │
│   │ pam_unix   │        │ pam_ldap   │        │ pam_radius │            │
│   │ (local)    │        │ (LDAP/AD)  │        │ (RADIUS)   │            │
│   └─────┬──────┘        └─────┬──────┘        └─────┬──────┘            │
│         │                     │                     │                   │
│         ▼                     ▼                     ▼                   │
│   /etc/shadow           LDAP Server           RADIUS Server             │
│                                                                         │
│   PAM Configuration (/etc/pam.d/common-auth):                           │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │ auth sufficient pam_unix.so nullok try_first_pass               │   │
│   │ auth sufficient pam_ldap.so use_first_pass                      │   │
│   │ auth required   pam_deny.so                                     │   │
│   └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

PAM module flow:

  • sufficient: If module succeeds, skip remaining; if fails, continue
  • required: Must pass, but continue checking other modules
  • requisite: Must pass, fail immediately if not

LDAP Authentication Flow

┌─────────────────────────────────────────────────────────────────────────┐
│                    LDAP Authentication Sequence                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   BMC (phosphor-user-manager)              LDAP Server                  │
│          │                                      │                       │
│          │  1. Bind (service account)           │                       │
│          │─────────────────────────────────────▶│                       │
│          │◀─────────────────────────────────────│ Bind success          │
│          │                                      │                       │
│          │  2. Search (find user DN)            │                       │
│          │  filter: (uid=username)              │                       │
│          │─────────────────────────────────────▶│                       │
│          │◀─────────────────────────────────────│ User DN returned      │
│          │                                      │                       │
│          │  3. Bind (user DN + password)        │                       │
│          │─────────────────────────────────────▶│                       │
│          │◀─────────────────────────────────────│ Auth success/fail     │
│          │                                      │                       │
│          │  4. Search (get group membership)    │                       │
│          │  filter: (member=userDN)             │                       │
│          │─────────────────────────────────────▶│                       │
│          │◀─────────────────────────────────────│ Group list            │
│          │                                      │                       │
│                                                                         │
│   Group to Privilege Mapping:                                           │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │ LDAP Group          │ OpenBMC Role      │ IPMI Privilege        │   │
│   ├─────────────────────┼───────────────────┼───────────────────────┤   │
│   │ cn=bmc-admins       │ Administrator     │ 4 (Administrator)     │   │
│   │ cn=bmc-operators    │ Operator          │ 3 (Operator)          │   │
│   │ cn=bmc-users        │ User              │ 2 (User)              │   │
│   │ cn=bmc-readonly     │ ReadOnly          │ 1 (Callback)          │   │
│   └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Password Hashing

┌─────────────────────────────────────────────────────────────────────────┐
│                    Password Storage                                     │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   /etc/shadow format:                                                   │
│   username:$6$salt$hash:lastchange:min:max:warn:inactive:expire:        │
│                                                                         │
│   Hash Types:                                                           │
│   ├── $1$ = MD5 (deprecated, insecure)                                  │
│   ├── $5$ = SHA-256                                                     │
│   └── $6$ = SHA-512 (default, recommended)                              │
│                                                                         │
│   Password Change Flow:                                                 │
│   ┌──────────────────────────────────────────────────────────────────┐  │
│   │ 1. Redfish PATCH /AccountService/Accounts/{id}                   │  │
│   │    { "Password": "newPassword" }                                 │  │
│   │                                                                  │  │
│   │ 2. bmcweb calls D-Bus:                                           │  │
│   │    xyz.openbmc_project.User.Manager.RenameUser() or              │  │
│   │    org.freedesktop.Accounts.User.SetPassword()                   │  │
│   │                                                                  │  │
│   │ 3. phosphor-user-manager:                                        │  │
│   │    - Validates password policy (length, complexity)              │  │
│   │    - Calls pam_chauthtok() to update /etc/shadow                 │  │
│   │    - Emits PropertiesChanged signal                              │  │
│   └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

D-Bus Permission Enforcement

┌─────────────────────────────────────────────────────────────────────────┐
│                    D-Bus Access Control                                 │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   /etc/dbus-1/system.d/ policy files control D-Bus access:              │
│                                                                         │
│   Example: phosphor-user-manager.conf                                   │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │ <policy user="root">                                            │   │
│   │   <allow own="xyz.openbmc_project.User.Manager"/>               │   │
│   │   <allow send_destination="xyz.openbmc_project.User.Manager"/>  │   │
│   │ </policy>                                                       │   │
│   │                                                                 │   │
│   │ <policy context="default">                                      │   │
│   │   <deny send_destination="xyz.openbmc_project.User.Manager"     │   │
│   │         send_interface="xyz.openbmc_project.User.Manager"/>     │   │
│   │   <allow send_destination="xyz.openbmc_project.User.Manager"    │   │
│   │         send_interface="org.freedesktop.DBus.Properties"        │   │
│   │         send_member="Get"/>                                     │   │
│   │ </policy>                                                       │   │
│   └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│   Privilege Enforcement in bmcweb:                                      │
│   ┌─────────────────────────────────────────────────────────────────┐   │
│   │ // Route with privilege requirement                             │   │
│   │ BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/") │   │
│   │     .privileges(redfish::privileges::patchAccount)              │   │
│   │     .methods(boost::beast::http::verb::patch)(handlePatch);     │   │
│   │                                                                 │   │
│   │ // privileges::patchAccount requires ConfigureUsers             │   │
│   └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Source Code Reference

Key implementation files in phosphor-user-manager:

File Description
user_mgr.cpp Main user manager implementation
users.cpp Individual user object handling
ldap_config.cpp LDAP configuration management
ldap_mapper.cpp LDAP group to privilege mapping
shadowlock.cpp /etc/shadow file locking
phosphor-ldap-conf.cpp LDAP config daemon

Examples

Working examples are available in the examples/user-manager directory:

  • user-management.sh - User CRUD operations script
  • ldap-config.json - LDAP configuration example

References


Tested on: OpenBMC master, QEMU romulus


Back to top

OpenBMC Guide Tutorial is not affiliated with the OpenBMC project. Content is provided for educational purposes.

This site uses Just the Docs, a documentation theme for Jekyll.