In Catalina running bash script via an AppleScript, results are not correct

Hi,


When I run below terminal cmd, the results are correct


Test-Catalinas-MacBook-Pro:~ catalina$ launchctl list | grep -v 'com.apple*'



Same commands triggered with applescript with administrator privileges, it retunrs me system launchd lists


sudo -u catalina launchctl list | grep -v 'com.apple*'



Also, I am not able query tcc.db from catalina using same approach. (bash script running via apple script)

sudo -u catalina sqlite3  /Library/Application\ Support/com.apple.TCC/TCC.db 'SELECT * from access' | grep kTCCServiceSystemPolicyAllFiles
sqlite3  /Library/Application\ Support/com.apple.TCC/TCC.db 'SELECT * from access' | grep kTCCServiceSystemPolicyAllFiles


DB query returns "unable to open"



My System Version: macOS 10.15 (19A573a)


To reproduce this:

  • create a bash script
  • run it with help of apple script


ASC below

set meFolder to (path tome) as string
 
 try
  set pathToScript to quoted form of ((POSIX path of meFolder) & "/Contents/Resources/Scripts/script.sh")
  end try

  try
  set scriptOutput to do shell script (pathToScript) with administrator privileges
endtry

Replies

Modern system require a special entitlement to access the TCC database. You can’t access it from un-entitled code, even if you run that code as root [1].

What are you trying to do with the TCC database?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] Turning off SIP disables this protection but, as we all learnt last week, turning off SIP is a bad idea on product systems.

Hi @eskimo,


Thank you for your reply.


What is meant by "un-entitled code"? Does it require notarization to run?


>>What are you trying to do with the TCC database?

sqlite3  /Library/Application\ Support/com.apple.TCC/TCC.db 'SELECT * from access' | grep kTCCServiceSystemPolicyAllFiles

I need to find the list of applications that are allowed for full disk access.


Also, please add comments to my first question on "launchd".


I am able to get correct output from terminal or apple script Editor, the issue is only when I integrate these commands with a simple bash script.

Apple's code has special privileges that your code doesn't have. Even if you are running it from bash, it is still running from an AppleScript context. I don't know the exact mechanisms of where this firewall is, but it causes the operating system to consider your script to be 3rd party code.


Apple isn't going to allow your app to find out this information. Sorry.

Also, please add comments to my first question on

launchd
.

You didn’t actually ask a question there. When you run

launchctl
without privileges, it targets the current session’s context. When you run it as root, it targets the global context. What are you trying to achieve?

What is meant by "un-entitled code"?

Apple platforms support the concept of entitlements. These are used by the system to gate access to various subsystems. Entitlements are part of the code signature, and thus can’t be ‘faked’ [1].

Entitlements fall into four rough categories:

  • Usable by any code — For example, any Mac app can opt in to the App Sandbox using the App Sandbox entitlement (

    com.apple.security.app-sandbox
    ).
  • Requires a provisioning profile — For example, apps from the same team can share keychain items courtesy of the Keychain Access Groups entitlement (

    keychain-access-groups
    ).
  • Special entitlements — These are available to third-party developers but must be explicitly granted by Apple. For example, the Hotspot Helper entitlement (

    com.apple.developer.networking.HotspotHelper
    ).
  • Apple only

The entitlements required to monkey with the TCC database fall into this last category. These are not publicly documented, but you can poke at various Apple tools to see what’s in play. For example:

$ codesign -d --entitlements :- /usr/bin/tccutil
…
<dict>
    <key>com.apple.private.tcc.manager</key>
    <true/>
</dict>
</plist>

I need to find the list of applications that are allowed for full disk access.

There is no supported way to do this.

Do you want this for a product that you intend to ship to customers? Or are you working in some sort of managed environment?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] Well, on the Mac you can turn off SIP and that gives you some latitude for hackery, but that’s not something I’m going to go into here.

I can see how tccutil has access to the database. But how come sqlite3 in the Terminal can access the database whereas the same sqlite3 command running from an AppleScript cannot?


I think this is an important issue. Developers often test things in an unprivileged Terminal window expecting the same commands to work in other contexts. And I'm not talking about sandbox, path, environment, or session issues. This seems to suggest that there is another layer of permissions that no one, or at least that neither the OP nor I, know about.


The OP is even doing too much work in the Terminal. The sudo command is not necessary to access that file. I'm running from a standard account and it works fine from the Terminal, but not AppleScript. In this case, Terminal has too many privileges. Is this by design? Is there any way to get Terminal to behave like an AppleScript or NSTask?

Hi eskimo,


Thank you again for your explainations.


Do you want this for a product that you intend to ship to customers? Or are you working in some sort of managed environment?

We are using this for troubleshooting purpose of our product to check whether the full disk access was allowed or not through a script.


Launchd output are different running same script from mojave and catalina.

But how come

sqlite3
in the Terminal can access the database … ?

That’s not my experience. From a freshly installed 10.15b9 [1]:

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15
BuildVersion:   19A573a
$ sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db
Error: unable to open database "/Library/Application Support/com.apple.TCC/TCC.db": unable to open database file

Likewise on a freshly installed 10.14.6:

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.6
BuildVersion:   18G95
$ sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db
Error: unable to open database "/Library/Application Support/com.apple.TCC/TCC.db": unable to open database file

If you’re seeing different results, it’s probably because either SIP is disabled or Terminal has been granted full disk access. I don’t have time to explore all those cases in depth today.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] I haven’t had time to update to b10 yet.

Launchd output are different running same script from mojave and catalina.

OK.

First, some background. AppleScript’s

with administrator privileges
is based on
AuthorizationExecuteWithPrivileges
. Historically that elevated privileges via a setuid binary. In 10.15 beta it seems that this changed to use a
launchd
daemon (
com.apple.security.authtrampoline
). In and of itself this change makes a lot of sense — setuid binaries are a security nightmare — but I suspect it’s interacting badly with the very-poorly-specified mechanism used by the
launchctl
legacy commands (like
list
) to decide what session to target.

However, I sat down to test this today and I wasn’t able to get it to produce different results on 10.14.6 and 10.15b9. For example:

To make this concrete, consider this:

$ cat test.applescript 
do shell script "launchctl list" with administrator privileges
$ sw_vers                    
ProductName:    Mac OS X
ProductVersion: 10.15
BuildVersion:   19A573a
$ osascript test.applescript 
-96 09atus  com.apple.storeassetd.daemononviceollerdondgwatcher823AA180000186A7

.

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.6
BuildVersion:   18G95
$ osascript test.applescript
-009    095tus  com.apple.storeassetd.daemononviceollerdond0-0000-0000-0000000186A8

I suspect there’s some subtlety in your script that I’m missing. Can you tweak the above example to show the specific problem you’re seeing.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

OK. I get it. The entitlement is to modify the database. I was a bit confused because my code looks at many low-level areas. I never modify anything, so that's something I never test. But it seemed strange that this security-related data would be so easily accessible when so many other, much more innocuous data, is protected so strongly against even read access.

Full Disk Access is managed on a per-app basis. Are you trying to have an app find out about its own Full Disk Access status? Or are you trying to find out the status of other apps?


If this is your own app, I suggest looking at a different location. As I hinted above, Apple's security restrictions are very complicated. Some locations are always accessible. Other locations are never accessible. I first ran into a problem trying to collect Time Machine information. I found that attempting to read "/Library/Preferences/com.apple.TimeMachine.plist" was a good way to determine if my app had Full Disk Access.


If you are looking for information about other apps, I guess you can use the TCC database via sqlite, as long as your script has Full Drive Access. You might need to write a simple little app that does nothing but that. Attempting to use an AppleScript, or any script really, introduces other risks and complexities. They might work. Might not. The simpler your solution is, the less likely that some minor Apple update will break it. Because of this, attempting to access the TCC database is risky. I think there is a high likelihood that Apple will remove read access as they have done with other, similar databases. In some cases, having root will help, but not with Full Disk Access.


For launchd, you want to use the "print" command instead of the "list" command. You will need to identify which domain you want to look at. But there are no print restrictions based on root. A standard user gets the same output from "launchctl print system/" as root. It can get a little tricky when you are looking at other, non-system domains.


Exactly what are you trying to accomplish with launchctl?

Hi All,


Thank you for the help. I had reported this via feedback assistant and below answer what I received today.

I am not sure that my script was not missing anything.



Apple

Oct 8, 2019 at 7:04 AM

We know. It’s not going to be fixed; it’s inherent in the new implementation of “with administrator privileges.” No action is planned, please close the feedback.