Need to find machines with Root enabled

tomt
Valued Contributor

Is there a flag I can use to create a search to find machines that have the Root User enabled?

Thanks,
Tom
------------------------------
Tom Tubbiola
Design IT
Ttubbiola at oakley.com
949.900.7705

26 REPLIES 26

leslie
Contributor II

Could generate an extension attribute:

dscl . -read /Users/root | grep AuthenticationAuthority | awk -F";" '{ print $2 }'

Believe you should get one of the three:
nothing - root has never been enabled
DisabledUser - root had been enabled but is now disabled
ShadowHash - root enabled

Leslie N. Helou
Senior Systems Engineer
Bell Techlogix
8888 Keystone Crossing, Suite 1700
Indianapolis, IN 46240
317.704.6408

jarednichols
Honored Contributor

Witness a disabled root users' Directory Services entry:

AppleMetaNodeLocation: /Local/Default
AuthenticationAuthority: ;DisabledUser;;ShadowHash;
GeneratedUID: FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000
NFSHomeDirectory: /var/root
Password: **
PrimaryGroupID: 0
RealName: System Administrator
RecordName: root
RecordType: dsRecTypeStandard:Users
SMBSID: S-1-5-18
UniqueID: 0
UserShell: /bin/sh

The key bit there is the AuthenticationAuthority, specifically ;DisabledUser;

We can search and grep this bit out and whip it into an Extension Attribute:

#!/sh/bin

rootStatus=dscl . -read /users/root | grep AuthenticationAuthority

case $rootStatus in
*;DisabledUser;*)
Echo "<result>Root Disabled</result>"
;;
*)
Echo "<result>Root Enabled</result>"
;;
Exit 0

I haven't tested this, YMMV, I am not a lawyer etc etc….

j

--
Jared F. Nichols
Desktop Engineer, Client Services
Information Services Department
MIT Lincoln Laboratory
244 Wood Street
Lexington, Massachusetts 02420
781.981.5436

tlarkin
Honored Contributor

Jared,

Nice one I was about to dive into this and you beat me to it :)

jarednichols
Honored Contributor

Crap. I forgot the "esac" at the end of my case statement.

Proofread your scripts, kids.
--
Jared F. Nichols
Desktop Engineer, Client Services
Information Services Department
MIT Lincoln Laboratory
244 Wood Street
Lexington, Massachusetts 02420
781.981.5436

jarednichols
Honored Contributor

Leslie beat us both :)

+1 for awk l337n3ss, Leslie.

j
--
Jared F. Nichols
Desktop Engineer, Client Services
Information Services Department
MIT Lincoln Laboratory
244 Wood Street
Lexington, Massachusetts 02420
781.981.5436

tlarkin
Honored Contributor

yeah I don't always receive emails in chronological order. Jared I
know you are white listed since I have been on this list for 4 years
now, but some of the people that don't post as much I think get wrangled
in my spam filters, and thus get delivered later.

-Tom

rockpapergoat
Contributor III

You can skip the grep and just use awk like so:

dscl . -read /Users/root | awk -F";" '/AuthenticationAuthority/ { print $2 }'

tomt
Valued Contributor

Thank you all. I have much to learn.

Tom
------------------------------
Tom Tubbiola
Design IT
Ttubbiola at oakley.com
949.900.7705

SeanA
Contributor III

This is a fascinating topic, though I have one discrepancy that I hope someone can explain.

On my 10.8.2 Mac, when Root User is disabled, either initially or after being once Enabled, in response to using ```
dscl . -read /Users/root
``` I do not have an "AuthenticationAuthority" entry. Only when Root User is enabled do I see such an entry. Thoughts?

Enabled User:

AppleMetaNodeLocation: /Local/Default
AuthenticationAuthority: ;Kerberosv5;;root@LKDC:SHA1.4AD38EDC88976575002A8804CC99D464CD5D7513;LKDC:SHA1.4AD38EDC88976575002A8804CC99D464CD5D7513 ;ShadowHash;HASHLIST:<SALTED-SHA512-PBKDF2>
GeneratedUID: FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000
NFSHomeDirectory: /var/root
Password: ********
PasswordPolicyOptions:
 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>failedLoginCount</key>
    <integer>0</integer>
    <key>failedLoginTimestamp</key>
    <date>2001-01-01T00:00:00Z</date>
    <key>lastLoginTimestamp</key>
    <date>2001-01-01T00:00:00Z</date>
    <key>passwordLastSetTime</key>
    <date>2013-01-18T17:36:48Z</date>
</dict>
</plist>

PrimaryGroupID: 0
RealName:
 System Administrator
RecordName:
 root
 BUILTINLocal System
RecordType: dsRecTypeStandard:Users
SMBSID: S-1-5-18
UniqueID: 0
UserShell: /usr/bin/false

Disabled User:

AppleMetaNodeLocation: /Local/Default
GeneratedUID: FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000
NFSHomeDirectory: /var/root
Password: *
PrimaryGroupID: 0
RealName:
 System Administrator
RecordName:
 root
 BUILTINLocal System
RecordType: dsRecTypeStandard:Users
SMBSID: S-1-5-18
UniqueID: 0
UserShell: /usr/bin/false

rmanly
Contributor III

Ditto on mine, looks like new behavior. <edit> This is a clean install of 10.8 though. Would be interesting to see what the record looks like on an updated machine. </edit>

This does the trick in 10.8.2 and the potentially installed developer seed that may or may not be available of the next point release.

#!/bin/bash

if dscl . read /Users/root | grep -q AuthenticationAuthority; then
    echo "<return>Enabled</return>"
else
    echo "<return>Disabled</return>"
fi

With a couple additions from scripts posted by many in the past or in RTrouton's github there is code to use sw_vers to check for different cats if you need something that will run on earlier OSes.

jwojda
Valued Contributor II

I need to modify this to look at UserShell results looking for "/usr/bin/false" - but when I try to put this in to terminal it doesn't give an output...

dscl . read /Users/root | grep -q UserShell

mm2270
Legendary Contributor II
dscl . -read /Users/root UserShell | awk '{print $NF}'

The above works for me, I get /bin/sh.
When using dscl, its always a good idea to try calling the attribute directlly with the syntax:

dscl . -read /Users/username <atttribute>

In many cases, the 'grep' isn't required at all. You still need to clean up the output if you want only the last column or some specific column, etc. BTW, the same would apply when pulling attributes from an AD account.

jhbush
Valued Contributor II

rmanly, for some reason your script is not returning a result when run as an EA via the JSS. When it's run locally it returns the proper value.

krusej23
New Contributor

jhbush1973, I am having the same issue. Have you found a solution to this?

jhbush
Valued Contributor II

@krusej23 no I still haven't found a fix for this. It may be due to the dscl failing if the field is not there.

tlarkin
Honored Contributor

Hi Everyone,

So for a test, I just ran a dscl query on my 10.9 VM before and after enabling the root account.

before:

109vm:~ tlarkin$ dscl . read /Users/root
AppleMetaNodeLocation: /Local/Default
GeneratedUID: FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000
NFSHomeDirectory: /var/root
Password: *
PrimaryGroupID: 0
RealName:
 System Administrator
RecordName:
 root
 BUILTINLocal System
RecordType: dsRecTypeStandard:Users
SMBSID: S-1-5-18
UniqueID: 0
UserShell: /bin/sh

and the after:

109vm:~ tlarkin$ dscl . read /Users/root
AppleMetaNodeLocation: /Local/Default
AuthenticationAuthority: ;Kerberosv5;;root@LKDC:SHA1.FB131D72AC61789DFDAB1A4C2388EC664DB15F7C;LKDC:SHA1.FB131D72AC61789DFDAB1A4C2388EC664DB15F7C ;ShadowHash;HASHLIST:<SALTED-SHA512-PBKDF2>
GeneratedUID: FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000
NFSHomeDirectory: /var/root
Password: ********
PasswordPolicyOptions:
 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>failedLoginCount</key>
    <integer>0</integer>
    <key>failedLoginTimestamp</key>
    <date>2001-01-01T00:00:00Z</date>
    <key>lastLoginTimestamp</key>
    <date>2001-01-01T00:00:00Z</date>
    <key>passwordLastSetTime</key>
    <date>2014-08-25T23:10:20Z</date>
</dict>
</plist>

PrimaryGroupID: 0
RealName:
 System Administrator
RecordName:
 root
 BUILTINLocal System
RecordType: dsRecTypeStandard:Users
SMBSID: S-1-5-18
UniqueID: 0
UserShell: /bin/sh

So, when disabled a lot less info is displayed. We can check exit codes of grep/awk to see if these directory service keys are present. Going off what @rmanly posted earlier is a good example.

So, an example when the root account is enabled:

109vm:~ tlarkin$ dscl . read /Users/root | grep AuthenticationAuthority 2>&1 > /dev/null ; echo $?
0

You see it returns 0, because grep successfully matched a string, and when disabled that same command:

109vm:~ tlarkin$ dscl . read /Users/root | grep AuthenticationAuthority 2>&1 > /dev/null ; echo $?
1

It returns exit code 1, because grep could not match a string. All I did to test this was enable/disable the root account via Director Utility. Another option would be to look at the `dsenableroot` binary in OS X, and when used with the -d flag it will force disabling of the root user. I suppose there are some things someone could do to hide or alter these directory service attributes even if the root user is enabled to mock what you are testing for. What would that break as far as functionality of the root user if someone went to that length, I have no idea. I did not test that. Unfortunately the dsenableroot command requires a password be used with it, so it may not be the best of scripting practices.

source: https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man8/dsenableroot.8....

Hope this helps.

Thanks,
Tom

jhbush
Valued Contributor II

@tlarkin thanks for the additional information. Taking what you added above seems to still not provide output as an EA in 9.4.

#!/bin/bash

rootCheck=`dscl . read /Users/root | grep AuthenticationAuthority 2>&1 > /dev/null ; echo $?`


if [ "${rootCheck}" == 1 ]; then

    echo "<return>Disabled</return>"

else

    echo "<return>Enabled</return>"

fi

tlarkin
Honored Contributor

@jhbush1973

Hey Jason, tomorrow morning when I am able to test this I will toss it in my test JSS. The code I wrote was just ran locally on my Mac as I was in between meetings onsite today. However, just real quick in the meantime, if you change your tags form <return> to <result> does the script then work?

Thanks,
Tom

jhbush
Valued Contributor II

@tlarkin][/url you are indeed correct. The script below returns the proper value. Thank you once again for your help.

#!/bin/bash

rootCheck=`dscl . read /Users/root | grep AuthenticationAuthority 2>&1 > /dev/null ; echo $?`


if [ "${rootCheck}" == 1 ]; then

    echo "<result>Disabled</result>"

else

    echo "<result>Enabled</result>"

fi

This version works as well.

#!/bin/bash

rootCheck=$(dscl . read /Users/root | grep AuthenticationAuthority > /dev/null 2>&1 ; echo $?)


if [ "${rootCheck}" == 1 ]; then

    echo "<result>Disabled</result>"

else

    echo "<result>Enabled</result>"

fi

linards
New Contributor

I was trying to install some pug-cli npm extension for jade templating, and run into root user issues. Ran into this error: Please try running this command again as root/Administrator. I know im logged in as a root, but still getting this error.

Then tried: -read /Users/root | awk -F";" '/AuthenticationAuthority/ { print $2 }'

and came back with this: ShadowHash

Any help on how to enable a root user appreciated.

Thanks.

georgecm12
Contributor III

I honestly can't think of anything that you would need root for that you can't do with "sudo -s" to give you a root shell.

The only reason I can think of that one would need to enable root is if one needed to do something as root in the GUI, and even that would be highly unusual.

donmontalvo
Esteemed Contributor II

Getting this on macOS Sierra:

$ dscl . read /Users/root | awk -F";" '/AuthenticationAuthority/ { print $2 }'
Kerberosv5

JoshRouthier
Contributor

Has anyone found a working solution for this in 10.14 or 10.15? Using @jhbush 's script, the AuthenticationAuthority line doesnt appear to show up in Mojave or Catalina when Root is enabled via Directory Utility or dsenableroot.

Ken_Bailey
New Contributor III

Curious if anybody has an update on this as well that could be used with Catalina or Big Sur.

Ken_Bailey
New Contributor III

I was able to get some help from apple. This seems to be working as an EA for a simple check.

#!/bin/sh

if [[ $(dscl . -read /Users/root Password) = *'Password: ********'* ]]; then
echo "<result>Enabled</result>"

else
echo "<result>Disabled</result>"
fi
exit

Can I use the script as it stands here with the asterisks as password or how may I understand this?

edit: tested, works perfect for me!