Any way to prevent local user creation?

Valued Contributor


We'd like to keep our domain users from being able to create other local users, while still allowing access to the User and Groups preference pane. Our users are developers so they all have local admin rights.

Anyone know how this could be done? Config profiles don't seem to be that granular.


Contributor II

Although I will open with LADIES and gents....

This might be fairly useful in our environment and am interested in seeing this solution

Not too sure on how it could be done but the thought I have is:
read from AD groups on local computer using DSCL and cross reference local computer accounts
if it doesnt exist then remove the local account

no doubt people will be able to script this before I can type #!/bin/bash

Legendary Contributor III

Just a question, but is the main goal to prevent login to the account, or was the interest in simply stopping any other account from being created, like not even one created from dscl with no home directory? If you're only looking for the former, there are some options, none that are great though. For the latter case, I honestly can't think of a way to stop that from happening.

Truthfully, once clients have admin access, all bets are off in terms of what you can really control, since its possible with enough know-how and research to bypass just about anything.

I had thought there were some old MCX options for the loginwindow to prevent login from certain types of accounts, but I don't think it actually would work in this case, and anyway, I can't even locate the settings I'm referring to, so they may only exist in my head :P

The only thing I can think of would be to create a LaunchDaemon and script, well disguised, that could watch the /Users/ directory, and upon seeing a change, check all accounts in that directory. Any that are not AD based or not part of an exclusion list could get disabled and/or deleted from the system. For future preventative measures, you could also send up a dialog to the user explaining that local accounts are not allowed, so they get the message.

Valued Contributor

If a user has administrative privileges, they can do whatever they like on the system. Entering a system administration "arms race" with an administrative user is a losing proposition for all. The determined and clever user will remove your launchdaemons, and if they're annoyed enough, they'll simply remove the framework.

If users must have administrative privileges, the best bet for avoiding problems is to educate users on why they shouldn't do certain things, define clear expectations and acceptable use policies, and get buy-in and enforcement from management/human resources for habitual violators.

I have often reminded users that the administrative privilege carries a responsibility to understand and refrain from doing things that would interfere with necessary IT functions.

Valued Contributor

Basically our security team doesn't want any user creating a non-domain account on the Mac...even if it's their family member, as that user account could be created to have admin rights and gain full access to the system and other users files.

That's the logic behind it.

Valued Contributor

@ooshnoo If the user already has administrative privileges with their domain account, that genie is already out of its proverbial bottle. If users are to have administrative privileges, then educating users on what they should or shouldn't do and having consequences for organization-damaging behavior is the order of the day.

Using the Casper Suite, you can report on the existence of administrative accounts on a Mac and if a computer is out of compliance with the organization's acceptable use policies, then the user can be auto-nagged, have certain profiles and settings removed, or have someone notified so disciplinary action can be taken.

What can't be done in any sensible or supported way is to grant administrative privileges but prevent the user from taking certain actions. Admin is admin. There's no "admin but can't do X". That's not how the technology works. Your security team is setting a requirement that doesn't reflect the realities of the situation. That's not uncommon.

New Contributor III

Just had a creatively amusing thought on this while mulling the same problem.

I may not be able to prevent them creating the account, but I can make it very unpleasant.

Reaches for toolbox, sets password policy to require passwords of no less than 128 characters in length...

Honored Contributor

I am pretty sure you cannot create a local admin account unless the account you are logged into is also an admin account. So if your users are already admins this would be sort of pointless. Also, what benefits do you get from forcing a domain account? Really the only benefit you get from using an AD account on a Mac is a Kerberos ticket, and if your Org highly leverages Kerberos as an authentication model then yes that is a benefit.

Otherwise there is really no security benefit, or at least nothing that can't be accomplished in better ways.

If you want to disable an account set that accounts default shell to /bin/false and that account is forever disabled until someone changes the default shell, or at least that used to be the case I haven't tested this method in a while. However, you will probably have to rube goldberg yourself a fancy workflow to accomplish doing this. I would recommend you get your info sec team to really define and validate the benefits of forcing AD accounts and non local accounts.

New Contributor III

In our environment (highly regulated financial), it is mandated that all accounts be AD managed accounts. However, we have developers who require admin privs and do like to create 'test' accounts for themselves on their devices.

We address this by compliance audits, but would also like to discourage/prevent them from doing so in first place to reduce the required effort on remediation.

New Contributor III

We're thinking about doing this to keep machines in line with inventory results. I'm pretty sure you could write a login script that checks for users with a specific UID range (iirc local accounts start with 501 but domain/mobile accounts start with a higher uid like 7 digitis in our environment) then log them out and delete the user. Probably with a message saying, "Please dont[...]."

Contributor II

This can be accomplished using the "security authorizationdb" command.
For details on the "security authorizationdb" command see Rich Trouton's blog.

Restrict admin users access to the Users & Groups (Accounts) system pref

/bin/echo "Restrict admin users access to the Users & Groups (Accounts) system pref"
/usr/bin/security authorizationdb read  system.preferences.accounts > /tmp/system.preferences.accounts.plist
/usr/bin/defaults write /tmp/system.preferences.accounts.plist group wheel
/usr/bin/security authorizationdb write system.preferences.accounts < /tmp/system.preferences.accounts.plist

Enable admin users access to the Users & Groups (Accounts) system pref

/bin/echo "Enable admin users access to the Users & Groups (Accounts) system pref"
/usr/bin/security authorizationdb read  system.preferences.accounts > /tmp/system.preferences.accounts.plist
/usr/bin/defaults write /tmp/system.preferences.accounts.plist group admin
/usr/bin/security authorizationdb write system.preferences.accounts < /tmp/system.preferences.accounts.plist


Bringing this back!
@ericbenfer I feel like this is close but an admin could still create new accounts or change passwords from the command line. Maybe modifying something in the system.identity.write dict would work? I'll play around with this on a test machine and see what happens. Could be pretty catastrophic if something goes wrong...

New Contributor III

My thought would be to deal with each method they would possibly use.
1. Configuration profile to disable the User/Groups Preference Pane. By doing this, you are disabling the convenient GUI.
2. Manage the /etc/sudoers file. You can get pretty granular with this method by creating command aliases to help cover all iterations of commands, specifying host names and users, or groups of users. Take a look at an example below.

This is an example snip-it. Here I am restricting a particular user. I can also apply this to the admin group for more broad coverage.

Cmnd_Alias    ACCT_CMDS    = /bin/passwd *, /usr/bin/dscl *,/usr/sbin/sysadminctl *
Cmnd_Alias    NOMODSUDO    = /bin/vi /etc/sudoers,/usr/sbin/visudo


A good explanation of the options are here

Valued Contributor


can you confirm this works with /etc/sudoers or /etc/sudoers.d? the last time i tried touching either of those in Sierra, the system froze. I see where you are coming from and have seen where those type of configurations work, just not sure on this platform anymore

New Contributor III

@Nix4Life It does for me in my environment, and I have a mix of 10.11 to 10.14. You just have to be sure you edit with visudo and I do believe also the permissions set properly otherwise, it may bug out.

Permissions have to be 440, owned by root and the wheel group.

I've found the aliases have to be declared before you use them in a rule. Order matters, and you want to make sure nothing is overriding your rules in /etc/sudoers.d

Always good to take a backup, edit the live file and if you have any issues then you have your working copy to go back to. Also, I make one or two changes at a time and test. There have been recommendations not to edit the /etc/sudoers file, but rather override with content in the /etc/sudoers.d . I modify the file.

Note: Some things won't work, like insults. This is because Apple modifies how sudo is compiled, and insults is a compile option as far as I am aware.

Here is how sudo is built on the Mac if you are interested. If something is a compile option, and it is not included here or in the libraries, it won't work.

sudo strings /usr/bin/sudo | fgrep -- '--with'
--with-password-timeout=0 --disable-setreuid --with-env-editor --with-pam --with-libraries=bsm --with-noexec=no --sysconfdir=/private/etc --without-lecture --enable-static-sudoers --with-rundir=/var/db/sudo

I do believe because --with-noexec=no, you cannot use the NOEXEC tag. I don't use the tag, so my scenario I am ok.

More info: