67

I'm trying to get a list of all users and all groups on Mac OS X 10.5+. How can I do this?

For example, the list of all users on my machine should return: _amavisd, _appowner, _appserver, _ard, _atsserver, _calendar, _carddav, _clamav, _coreaudiod, _cvmsroot, _cvs, _cyrus, _devdocs, _dovecot, _eppc, _installer, _jabber, _lda, _locationd, _lp, _mailman, _mcxalr, _mdnsresponder, _mysql, _pcastagent, _pcastserver, _postfix, _qtss, _sandbox, _screensaver, _securityagent, _serialnumberd, _softwareupdate, _spotlight, _sshd, _svn, _teamsserver, _timezone, _tokend, _trustevaluationagent, _unknown, _update_sharing, _usbmuxd, _uucp, _windowserver, _www, _xgridagent, _xgridcontroller, daemon, dave, nobody, root (that was painstakingly compiled manually).

How can I get that list (and the corresponding list of all groups) programmatically? I'm open to alternative (non-c based) solutions, such as Applescript, commandline, etc.


Update a long time later

TALlama's answer prompted me to investigate the API to Open Directory, and I found that this list can be easily acquired programmatically:

#import <OpenDirectory/OpenDirectory.h>
ODSession *s = [ODSession defaultSession];
ODNode *root = [ODNode nodeWithSession:s name:@"/Local/Default" error:nil];
ODQuery *q = [ODQuery queryWithNode:root forRecordTypes:kODRecordTypeUsers attribute:nil matchType:0 queryValues:nil returnAttributes:nil maximumResults:0 error:nil];

NSArray *results = [q resultsAllowingPartial:NO error:nil];
for (ODRecord *r in results) {
    NSLog(@"%@", [r recordName]);
}

That will log the usernames of every user on the system. Substituting in kODRecordTypeGroups will get you the list of all the groups.

The -[ODQuery resultsAllowingPartial:error:] method is a blocking call, so you'd either want to execute this code on a background thread, or use an <ODQueryDelegate> to aggregate the results.

Community
  • 1
  • 1
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • Sadly, the fact that you were able to make that exhaustive list manually suggests that you already had a way to automate it. You presumably read a list of directory names or something? Great question to ask though. Google turned up the answer in about 15 seconds. – TheJacobTaylor Aug 20 '09 at 03:28
  • I got it from another program. – Dave DeLong Aug 20 '09 at 03:34
  • Clarification: the other program had the list in a popupbutton, and I copied it out. I want a similar popupbutton. =) As for google, I spent a while searching for variations on "mac get list of all users" and couldn't find anything relevant. – Dave DeLong Aug 20 '09 at 03:36
  • Is there a pure obj-c way (without calling command line tool) ? – AP. Jun 16 '11 at 06:26
  • @AP. (A long time later) I was playing around with this the other day and came up with some code to do this. – Dave DeLong Jan 27 '13 at 17:35
  • @Dave :Thanks for the update – AP. Feb 04 '13 at 06:27
  • I took your suggestion (the OpenDirectory code) as my start-point and it is great - however, I now need to get group membership for each one of the users... what "id -Gn " command-line gives you... and I just can't get the hang of this OpenDirectory API – Motti Shneor Dec 30 '20 at 16:06

5 Answers5

119

The tool you want is almost certainly dscl. The shortest way to do it was already pointed out:

$ dscl . list /users
$ dscl . list /groups

If you want to output information about each user, though, use readall:

$ dscl . readall /users
$ dscl . readall /groups

And if you need to programatically parse said information, use -plist to make your life easier:

$ dscl -plist . readall /users
$ dscl -plist . readall /groups
TALlama
  • 16,017
  • 8
  • 38
  • 47
  • For some reason, this does not list all users, even if I run with sudo. It doesn't show any of the "real" users, just the system-ish ones. – cheshirekow Jul 21 '11 at 17:51
  • Works on my Lion install; what OS are you seeing it fail with? – TALlama Jul 21 '11 at 20:35
  • 1.5.8. I figured it out. I didn't realize there were several different ways that osx can authenticate. Turns out I needed JacobTaylor's "Open Directory" approach. – cheshirekow Jul 21 '11 at 21:27
  • 7
    Note: `dscl -list` is limited to 256 results, so this is not guaranteed to list all user accounts. – smokris Sep 14 '12 at 19:03
  • 1
    that's hardly a programmatic way to do it from my application. Any API? – Motti Shneor Dec 29 '20 at 09:28
12

Open Directory approach (from: http://rickcogley.blogspot.com/2008/11/listing-open-directory-users-on-os-x.html):

dscacheutil -q user
dscacheutil -q group

Take each line from the respective output that starts with "name:" strip off the "name:" and you have your list. If you do not have dscacheutil, you can use the manual commands:

root# dscl localhost list /Local/Default/Users
root# dscl localhost list /LDAPv3/127.0.0.1/Users

Old school approach for before Open Directory....(sigh): For list of users:

  • Grab the /etc/passwd file from the system.
  • Split it out by lines
  • Split out each line based on ":"
  • Take the first symbol for each line

For list of groups:

  • Grab the /etc/group file from the system.
  • Split it out by lines
  • Split out each line based on ":"
  • Take the first symbol for each line
TheJacobTaylor
  • 4,063
  • 1
  • 21
  • 23
  • 2
    I don't think this works - grepping `/etc/passwd` on my mac doesn't yield my username. – Peter Aug 20 '09 at 02:01
  • +1 same here, but it seems like it has everything else. Thanks! I'll keep this open in case there's a better way. – Dave DeLong Aug 20 '09 at 02:06
  • 4
    I believe that Directory Services replaces `/etc/passwd`. The file is probably only there for legacy reasons. – Dana the Sane Aug 20 '09 at 02:08
  • 2
    Note: `dscacheutil -q user` and `dscl -list` are limited to 256 results, so this is not guaranteed to list all user accounts. – smokris Sep 14 '12 at 19:05
  • Here too (MacOS 10.15.7) - "normal" Mac users, created via the "Users & Groups" UI (in System Preferences) don't appear in /etc/passwd file. Maybe there's another such file (same format) that extends it for the "Mac users" ? – Motti Shneor Dec 29 '20 at 09:32
10

Non-garbbled/no-tempfile commands:

# dscl . list /users
# dscl . list /groups
eduffy
  • 39,140
  • 13
  • 95
  • 92
  • Wow, even better! I love this site! =) – Dave DeLong Aug 20 '09 at 02:22
  • 1
    Note: `dscl -list` is limited to 256 results, so this is not guaranteed to list all user accounts. – smokris Sep 14 '12 at 19:04
  • Is there a programmatic API to get to the same functionality? I don't wish to create an external process via NSTask, collect and parse its text output every time my Cocoa application needs the list of users... maybe that's normal for UniX style programming, but not for Mac programming. – Motti Shneor Dec 29 '20 at 09:46
2

Back in the old days, we'd do this trivially with the NetInfo Kit, but today there's no tidy Objective-C way to do it. You'll have to dig in to the OpenDirectory API.

NSResponder
  • 16,861
  • 7
  • 32
  • 46
1

check out, for example, dsexport.

Here are some examples:

dsexport /tmp/export.out /Local/Default dsRecTypeStandard:Groups

dsexport /tmp/export.out /Local/Default dsRecTypeStandard:Users

the outputs are a bit rubbish, but something like sed could clean them up for you.

Peter
  • 127,331
  • 53
  • 180
  • 211