Stuck in macOS plist purgatory again

Dictionaries or dictionaries of dictionaries… yay.

I looked to the answers in one of my past posts on macOS plists for guidance, but found little in there that helped this time. Anyone want to join me in this “fun”?

Again, I’m trying to “browse” my way though a macOS plist to both list out certain information and look for specific values. The plist in question is “/Library/Application Support/com.apple.TCC/MDMOverrides.plist”, a heavily trimmed example of which is below:

Dict {
    com.crowdstrike.falcon.Agent = Dict {
        kTCCServiceSystemPolicyAllFiles = Dict {
            Allowed = 1
        }
    }
    com.crowdstrike.falcon.App = Dict {
        kTCCServiceSystemPolicyAllFiles = Dict {
            Allowed = 1
        }
    }
    com.apple.Terminal = Dict {
        kTCCServiceAccessibility = Dict {
            Allowed = 1
        }
        kTCCServiceSystemPolicyAllFiles = Dict {
            Allowed = 1
        }
        kTCCServiceReminders = Dict {
            Allowed = 1
        }
        kTCCServiceAddressBook = Dict {
            Allowed = 1
        }
    }
}

Minimally, I need to be able to identify computers that have, for example, a value of 1 for Allowed under kTCCServiceSystemPolicyAllFiles for com.apple.Terminal (or something similar to that).

Ideally, I’d ALSO like to list out this plist with those values and paths on one line:

MDM|allw|com.apple.Terminal|kTCCServiceAccessibility
MDM|allw|com.apple.Terminal|kTCCServiceAddressBook
MDM|allw|com.apple.Terminal|kTCCServiceReminders
MDM|allw|com.apple.Terminal|kTCCServiceSystemPolicyAllFiles
MDM|allw|com.crowdstrike.falcon.Agent|kTCCServiceSystemPolicyAllFiles
MDM|allw|com.crowdstrike.falcon.App|kTCCServiceSystemPolicyAllFiles

I’ve written a shell script (that I’m very proud of, using PlistBuddy and sqlite) that does this, but I’d much rather do this with inspectors than with eternal actions that rewrite a file once a day to be read by an analysis.

Frustratingly, I’ve only gotten as far as this:

Q: keys of entries of dictionaries of file "/Library/Application Support/com.apple.TCC/MDMOverrides.plist"
A: com.screenconnect.client.access
A: com.jamf.management.Jamf
A: com.crowdstrike.falcon.Agent
A: com.crowdstrike.falcon.App
A: /usr/bin/osascript
A: com.apple.Terminal
A: /usr/local/jamf/bin/jamf
T: 395

Any other combinations of keys and entries and dictionaries and values and strings (probed in a bazillion ways with exists) has gotten me nothing but
E: The operator "everything-I've-tried" is not defined.

What am I missing that will get me into that next level of Dante’s dictionary inferno to pull out the bit of brimstone that I need?

Perhaps it’ll be easier to write relevance against the output of:
sudo profiles show type=configuration

Better yet, have an action that pipes this output into some python/perl/awk/etc that munges into an analysis-friendly format?

I believe the -showtypes parameter is valid for the Mac version of QNA, and it might be helpful to see what type is being returned.

Once you know the type, you can use an introspector to see what properties are available for that type, i.e.

Q: properties of type "json key"

Just riffing here, but maybe one can use plutil to dump the plist to json, and work from there?

1 Like

For any who may find this later (including myself!), I figured it out. :sweat: :crazy_face:

Q: (integer of value of it) of (entries of dictionary "kTCCServiceSystemPolicyAllFiles" of dictionary "com.apple.Terminal" of dictionary of file "/Library/Application Support/com.apple.TCC/MDMOverrides.plist") whose (key of it = "Allowed")
A: 1

so

Q: (integer of value of it = 1) of (entries of dictionary "kTCCServiceSystemPolicyAllFiles" of dictionary "com.apple.Terminal" of dictionary of file "/Library/Application Support/com.apple.TCC/MDMOverrides.plist") whose (key of it = "Allowed")
A: True

I hate plists. :face_with_symbols_over_mouth:

So, the endgame for all of this was to find a way to identify macOS computers where Terminal had been granted Full Disk Access in order to know whether a bash script would run successfully or not. Here’s the relevance for that which checks both the MDMOverrides.plist and the TCC.db:

Q: ( (integer of value of it = 1) of (entry of dictionary "kTCCServiceSystemPolicyAllFiles" of dictionary "com.apple.Terminal" of dictionary of file "/Library/Application Support/com.apple.TCC/MDMOverrides.plist") whose (key of it = "Allowed") | False ) OR ( exists (row of statement "select client,service from access where auth_value != '0'" of sqlite database of file "/Library/Application Support/com.apple.TCC/TCC.db") whose (it as string = "com.apple.Terminal,kTCCServiceSystemPolicyAllFiles") | False )
A: True
5 Likes

Daaaaang. Well done!

1 Like

Hey @straffin, was all of this so that you could run a bash script independently, or from BigFix?

Right now I’m trying to get BESAgent to access files in /Users/*/Desktop, but it cannot. Even though com.bigfix.BESAgent has the TCC grant for User’s Desktop Files.

tccd: [com.apple.TCC:access] Refusing TCCAccessRequest for service kTCCServiceSystemPolicyDesktopFolder from client Sub:{com.bigfix.BESAgent}Resp:{TCCDProcess: identifier=com.bigfix.BESAgent, pid=67513, auid=0, euid=0, responsible_path=/Library/BESAgent/BESAgent.app/Contents/MacOS/BESAgent, binary_path=/Library/BESAgent/BESAgent.app/Contents/MacOS/BESAgent} in background session

Now I’m wondering if com.apple.bash needs a grant for User’s Desktop Files? :thinking:

1 Like

Hmm… I’ve been looking at/for Terminal. Sounds like I’m doing that wrong…