Managing users and groups from the OS X terminal

I was recently playing around with SaltStack and wanted to create a salt user and group to run the master. This led me to learn some basics of user and group management on OS X, and I thought I’d put them here to remember. FYI I did all this on Yosemite, but it seems like this is the way things have worked for a while, so it should work on just about any OS X system that’s still running I would think. No guarantees though.

First things first: there’s no useradd command like on standard *nix systems. Instead, OS X uses dscl, the “Directory Service command line utility”, to manage users. I’ll let Wikipedia explain what a directory service is. It seems like one of those fairly simple concepts that becomes shrouded in terminology and abstraction, so I’m going to make a hand wavey attempt at explaining what I’ve intuited. The abstraction for datasources is directories (hence the name I guess), so things tend to look like paths on a filesystem. From the man pages, dscl deals in paths and keys, where paths are what you’d expect and keys are like the leaves of a tree (think files in directories) that store facts about path they’re in. For our purposes, users and groups are paths that contain keys with facts about that user or group. Hopefully this will become clear when we run some commands. Finally, dscl operates on datasources, which can be local or remote – e.g. other servers running a directory service. Everything we do will be on the local datasource (i.e. the computer you’re running the commands on), so our first argument to dscl will always be a ‘.’ to signify the local datasource.

Before we start using sudo and making changes, let’s start with some queries to get comfortable. I’ve fabricated the output of commands based on real output, as well as trimmed a bunch of data to save on space, but you should get the idea.

# List the subdirectories under /Users - i.e. list the users on the system
$ dscl . -list /Users

# List the subdirectories under /Groups - i.e. the groups on the system
$ dscl . -list /Groups

# Read all keys in directory and output their values
$ dscl . -read /Users/purpletentacle
PrimaryGroupID: 42
 Purple Tentacle
UniqueID: 505
UserShell: /bin/bash

# Read a specific key
$ dscl . -read /Users/purpletentacle UniqueID
UniqueID: 505

# List paths with the value of a key
$ dscl . -list /Users UniqueID
greententacle	501
purpletentacle	505
bernard			502

We can use dscl to modify this information, or in our case, add new information. We’re about to create a new user and group, but before we do I should mention that while you can add a new group with dscl, it’s better to use dseditgroup as explained on Super User.

# Add the humans group. See man page for explanation of options.
$ sudo dseditgroup -o create -r "Group for Humans not tentacles" humans

# Get the current highest user ID so we can pick something higher
$ dscl . -list /Users UniqueID | awk '{print $3}' | sort -n | tail -1

# Create the user
$ sudo dscl . -create /Users/hoagie 
$ sudo dscl . -create /Users/hoagie UniqueID <one more than current highest above>
$ sudo dscl . -create /Users/hoagie UserShell /bin/bash # /usr/bin/false if you don't want the user to have a shell 
$ sudo dscl . -create /Users/hoagie RealName "Hoagie"

# Add user to group
$ sudo dseditgroup -o edit -a hoagie -t user humans

That’s about all there is. Once you get a feel for these commands, their man pages should be accessible enough to work out anything else you want to do.


3 thoughts on “Managing users and groups from the OS X terminal

  1. Really useful material. Thanks. I have a question though. Is it possible to change a UID:GID of a username? I have a situation here where I have the same UID:GID for root and dovenull. I’d like to make dovenull say 5050:5050 and leave root 0 – without totally trashing the system?

    dscl . -list /Users UniqueID
    dovecot 0
    dove null 0
    root 0

    and both of them under the group wheel – also 0

    Thanks if you have any ideas on that.

  2. Ok, fixed it.
    sudo dscl . create /Users/username PrimaryGroupID 450
    sudo dscl . create /Users/username UniqueID 450

    These change the aid:did to 450, so although it says create, it actually updates/changes it. It leaves root with the unique 0 id.

  3. Sorry for my late reply – I’ve been away this past week. Glad to hear you found the post useful and that you managed to find a fix :).

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>