Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to manually install a daemon (Oracle Grid Engine) on my machine, and I would like it to run under an isolated account. What is the preferred way, using Directory Services, to add a "system" account to the local machine on OS X? Plenty of them exist in /etc/passwd (_www, _dovecot, etc.), but comments at the top of that file say that it isn't used except in single-user mode.

I'm running on 10.6, and do not require any special networked account management. I'm hoping for something simple--the equivalent of useradd on nearly every other Unix-like OS.

share|improve this question

4 Answers 4

up vote 2 down vote accepted

dscl is the command you are looking for.

share|improve this answer
    
+1 because this is the definitive answer. If you want a GUI, you can download the Server Tools and point Workgroup Manager at your own machine to do essentially the same thing.. –  Johnnie Odom Sep 17 '10 at 21:35

I tried the script from par, and found a few issues. So I modified it for one specific userid and for OS X Mavericks (10.9).

I found that there was a couple extraneous records added to the User account under Mavericks -- a PasswordPolicyOptions and an AuthenticationAuthority record -- that needed to be removed to correctly mimic other builtin service user accounts (like _www).

I also added the Password and RealName records to the Group account.

I created a custom, one off, script just for a WSGI service account. Here's the updated script.

#! /bin/bash
#

# Check that we are superuser (i.e. $(id -u) is zero)
if (( $(id -u) ))
then
    echo "This script needs to run as root"
    exit 1
fi

username_=wsgi
uid_=240
realname_="WSGI Daemon"

dscl . -create /Groups/_$username_
dscl . -create /Groups/_$username_ PrimaryGroupID $uid_
dscl . -create /Groups/_$username_ RecordName _$username_ $username_
dscl . -create /Groups/_$username_ RealName $realname_
dscl . -create /Groups/_$username_ Password \*

dscl . -create /Users/_$username_
dscl . -create /Users/_$username_ NFSHomeDirectory /xpt/local/apache2/wsgi/api
dscl . -create /Users/_$username_ Password \*
dscl . -create /Users/_$username_ PrimaryGroupID $uid_
dscl . -create /Users/_$username_ RealName $realname_
dscl . -create /Users/_$username_ RecordName _$username_ $username_
dscl . -create /Users/_$username_ UniqueID $uid_
dscl . -create /Users/_$username_ UserShell /usr/bin/false
dscl . -delete /Users/_$username_ PasswordPolicyOptions
dscl . -delete /Users/_$username_ AuthenticationAuthority

Note that after running this script the /etc/passwd and /etc/groups files are not updated. I believe they are updated on reboot.

share|improve this answer
    
Thanks Dave. I updated my script (below) to use your Mavericks discoveries and take an optional real-name parameter. –  par Jan 10 at 5:40

EDIT: Updated Jan 9, 2014 for OS X Mavericks (suggestions from Dave, thanks!)

I wrote a bash script to do this. It will use the first unused uid which is less than or equal to 500 (daemon account uids on Mac OS X) that also has an identical unused gid.

Save the script to a file named add_system_user.sh and set it executable with chmod 755 add_system_user.sh.

Then let's say you want to add a daemon/system user called par. You would run this script like so:

sudo add_system_user.sh par

And you will get a system user called _par which is aliased to par (the name you requested) and has a matching uid and gid (e.g. 499 or whatever it found).

Here's the script:

#!/bin/bash

if (( $(id -u) )) ; then
    echo "This script needs to run as root"
    exit 1
fi

if [[ -z "$1" ]] ; then
    echo "Usage: $(basename $0) [username] [realname (optional)]"
    exit 1
fi

username=$1
realname="${2:-$username}"

echo "Adding daemon user $username with real name \"$realname\""

for (( uid = 500;; --uid )) ; do
    if ! id -u $uid &>/dev/null; then
        if ! dscl /Local/Default -ls Groups gid | grep -q [^0-9]$uid\$ ; then
          dscl /Local/Default -create Groups/_$username
          dscl /Local/Default -create Groups/_$username Password \*
          dscl /Local/Default -create Groups/_$username PrimaryGroupID $uid
          dscl /Local/Default -create Groups/_$username RealName "$realname"
          dscl /Local/Default -create Groups/_$username RecordName _$username $username

          dscl /Local/Default -create Users/_$username
          dscl /Local/Default -create Users/_$username NFSHomeDirectory /var/empty
          dscl /Local/Default -create Users/_$username Password \*
          dscl /Local/Default -create Users/_$username PrimaryGroupID $uid
          dscl /Local/Default -create Users/_$username RealName "$realname"
          dscl /Local/Default -create Users/_$username RecordName _$username $username
          dscl /Local/Default -create Users/_$username UniqueID $uid
          dscl /Local/Default -create Users/_$username UserShell /usr/bin/false

          dscl /Local/Default -delete /Users/_$username AuthenticationAuthority
          dscl /Local/Default -delete /Users/_$username PasswordPolicyOptions
          break
        fi
    fi
done

echo -e "Created system user $username (uid/gid $uid):\n"

dscl /Local/Default -read Users/_$username

echo -e "\nYou can undo the creation of this user by issuing the following commands:\n"
echo "sudo dscl /Local/Default -delete Users/_$username"
echo "sudo dscl /Local/Default -delete Groups/_$username"
share|improve this answer
    
This worked well for me on 10.9. Thanks! –  jbyler 2 days ago

Here's an article that explains how to use dscl to create a user account.

osxdaily.com article

share|improve this answer
    
Thanks. The man pages tell you what commands you can use, but don't give you any help on what fields to use and what to set them to. I was just going to copy the config from another account, but this gives a good example. –  Tim Yates Sep 17 '10 at 23:12
    
For a hidden system account, take a look at some existing system accounts for better examples. E.g. dscl /Local/Default -read /Users/_sshd (dscl /Local/Default -ls /Users will get you a list of local accounts). Note that you don't have to set all attributes; GeneratedUID is generated randomly, and RecordType is automatic metadata. Also, most OS X system accounts have a primary account name that starts with underscore, and an alias without it for backward compatibility; I recommend using the underscore convention, but don't bother with the plain alias unless you need to. –  Gordon Davisson Sep 18 '10 at 1:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.