jelockwood / pinpoint

A script for finding your Mac
GNU General Public License v3.0
28 stars 5 forks source link

Compatibility issues with macOS Sonoma 14.4 and later #25

Open jelockwood opened 4 months ago

jelockwood commented 4 months ago

@kevinmcox As brought to my attention by @ofirgalcon, Apple have deprecated the -

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport

binary in macOS Sonoma 14.4. When executed it now only produces the following.

WARNING: The airport command line tool is deprecated and will be removed in a future release.
For diagnosing Wi-Fi related issues, use the Wireless Diagnostics app or wdutil command line tool.

I have already determined that the following Python script can be used as the basis of an alternative to the Apple airport binary.

#!/usr/bin/env pythonw

import objc
objc.loadBundle(
    "CoreWLAN",
    bundle_path="/System/Library/Frameworks/CoreWLAN.framework",
    module_globals=globals()
)
from CoreWLAN import CWNetwork, CWWiFiClient
client = CWWiFiClient.sharedWiFiClient()
iface = client.interfaceWithName_("en0")
networks, error = iface.scanForNetworksWithName_error_(
    None,
    None,
)

for i in networks:
    if i.ssid() is None:
         continue
    print({'SSID_STR': i.ssid(), 'BSSID': i.bssid(), 'RSSI': i.rssiValue(), 'CHANNEL': i.channel()})

The above Python script however needs a lot more work to get it to format the results in the same way that the airport binary did. (Feel free to contribute improvements to this Python script.) It also needs improving to automatically pick the correct network interface.

jelockwood commented 4 months ago

FYI, I have determined that the following commonly used copies of Python3 for the Mac do or do not include CoreWLAN support which is required.

MacAdmins Python3 3.9.10 = Yes AutoPkg Python 3.10.4 = No Munki Python 3.10.11 = No

Versions newer than the above will likely have the same results so MacAdmins Python3 3.12.1 will also have CoreWLAN included as standard.

jelockwood commented 4 months ago

@thewade Eeek!

I had been doing most of my testing on an older macOS. I have now just done testing in macOS 14.4 and it appears that not only are Apple blocking the BSSID field but now they are also blocking the SSID field as well!!!

I think if you know the SSID you are looking for you can search for that specifically, but it seems you now can not do a general scan. Here is what it looks like.

{( <CWNetwork: 0x6000009ac4b0> [ssid=(null), bssid=(null), security=WPA2 Personal, rssi=-53, channel=<CWChannel: 0x6000009a2570> [channelNumber=6(2GHz), channelWidth={20MHz}], ibss=0], <CWNetwork: 0x6000009ac530> [ssid=(null), bssid=(null), security=WPA2/WPA3 Personal, rssi=-73, channel=<CWChannel: 0x6000009a25a0> [channelNumber=11(2GHz), channelWidth={20MHz}], ibss=0], )}

Any ideas how to get the SSID - this is particularly critical, I could probably have survived without the countrycode

xavier-contreras commented 3 months ago

@thewade Eeek!

I had been doing most of my testing on an older macOS. I have now just done testing in macOS 14.4 and it appears that not only are Apple blocking the BSSID field but now they are also blocking the SSID field as well!!!

I think if you know the SSID you are looking for you can search for that specifically, but it seems you now can not do a general scan. Here is what it looks like.

{( <CWNetwork: 0x6000009ac4b0> [ssid=(null), bssid=(null), security=WPA2 Personal, rssi=-53, channel=<CWChannel: 0x6000009a2570> [channelNumber=6(2GHz), channelWidth={20MHz}], ibss=0], <CWNetwork: 0x6000009ac530> [ssid=(null), bssid=(null), security=WPA2/WPA3 Personal, rssi=-73, channel=<CWChannel: 0x6000009a25a0> [channelNumber=11(2GHz), channelWidth={20MHz}], ibss=0], )}

Any ideas how to get the SSID - this is particularly critical, I could probably have survived without the countrycode

On newer OSX releases, the BSSID field was only obtainable if you ran the command with "sudo". I suspect that may have something to do with it not returning.

Thanks for the script by the way, will come in handy till a proper solution is in place. But yes, calling this at least narrows things down to the SSID you are looking for:

iface.scanForNetworksWithName_error_(
    "MySSID",
    None,
)
jelockwood commented 3 months ago

@xavier-contreras With the help of thewade I now have a fully working solution. The key is to give Python permission to use Location Services. It can then retrieve the blocked fields including SSID and BSSID and countrycode.

The full working script is available at -

pinpoint_scan.py

xavier-contreras commented 3 months ago

@jelockwood that's very helpful, thank you!

precursorca commented 1 month ago

I found that the 3.2.7 release pkg did not actually have the python script nor the calls to it in the shell script so I downloaded the code in the main branch and installed MacAdmins Python 3.12.

I found that that the shell could not correctly call the python script because the shell script runs as root from the launch daemon so I added code to let the python script run as the user and after testing I made a pull request.

The problem remaining for me is that installing MacAdmins Python 3.12 is still incompatible with munkireport 5.8 so I had to reinstall the recommended Python for munkireport 5.8 and will not be doing anymore testing until that part of the story is resolved.

jelockwood commented 1 month ago

@precursorca Regarding 3.2.7 not having the Python script nor calls to it from the shell script.

This is actually correct, 3.2.7 predates those changes. I have not yet released an official new version incorporating these changes - you can see that the shell script is labelled as 3.3b and the release will therefore be 3.3.

I have been too busy to finish this at work recently, I also do not have a Google license I can use for testing in my current job. I do believe the Python script is complete and working and it can be run by itself to act as a replacement for the Apple AirPort command. Can you indicate if you have tried the Python script by itself and did it work for you?

Once you have confirmed the Python script works for you I could create a beta release of 3.3 for you to then try and I can look to include your pushed update as well. It would be very helpful if you could then test that beta release and confirm if they work for you also.

Regarding the MunkiReport and MacAdmins Python compatibility issue.

I see that MunkiReport has been updated last year to actually require using the MacAdmins Python although it mentions that it does not support the latest MacAdmins version and recommends using the 3.10 version.

I have not tested that version with my Python script but would feel that it is likely to work with my script.

This is mentioned here - https://www.kevinmcox.com/2023/06/munkireport-python-3-and-php-8/

The link to the 3.10 version is here - https://github.com/macadmins/python/releases/tag/v3.10.9.80716

I should be able to test 'downgrading' to that version of the MacAdmins Python and test that for you as well.

FYI - I don't currently run MunkiReport myself although I have plans to hopefully do so again so thanks for bringing this to my attention. Ironically, a different 'project' I have done is an AutoPkg recipe which would automate downloading the latest MacAdmins Python installer and adding it to Munki to keep my clients updated.

precursorca commented 1 month ago

Python script In terminal

This works: sudo /usr/local/bin/managed_python3 /Library/Application\ Support/pinpoint/bin/pinpoint_scan.py

Without sudo it does not and errors out as I indicated /usr/local/bin/managed_python3 /Library/Application\ Support/pinpoint/bin/pinpoint_scan.py

Shell script Also in terminal

sudo sh /Library/Application\ Support/pinpoint/bin/pinpoint.sh The python part errors out and so the rest of the script stops

Without sudo sh /Library/Application\ Support/pinpoint/bin/pinpoint.sh The python gets called and works but the rest of the script fails to write to the plist.

That is why I added the part about running the python script as the user in my pull request. With that change this works sudo sh /Library/Application\ Support/pinpoint/bin/pinpoint.sh

And also more importantly the module works when the launchdaemon runs the script. A proper plist gets written.

— munkireport 5.8 only works with python 3.10 It fails on 3.11 and 3.12 because of a problem with PyobjC (according to Tuxedo). Tuxudo is aware of the issue but has not had time to write a shim to fix it. So munkireport is stuck at 5.8

I inspected MacAdmins Python 3.10 and it does not have CoreWLAN support. Nor does the currently shipping Python in AutoPKGr Nor does the currently shipping Python in munki 6.5

So once Tuxudo can get munkireport ready to work MacAdmins Python 3.12 we should be in better shape.

If you have a beta I could test it but I would have to dedicate a machine that can go off munkireport for a while.

I have a functioning google account and use pinpoint via munkireport across 30 clients (their MacBooks only; not on their Desktop computers).


Alex Narvey @.***

On May 23, 2024, at 8:54 PM, jelockwood @.***> wrote:

@precursorca https://github.com/precursorca Regarding 3.2.7 not having the Python script nor calls to it from the shell script.

This is actually correct, 3.2.7 predates those changes. I have not yet released an official new version incorporating these changes - you can see that the shell script is labelled as 3.3b and the release will therefore be 3.3.

I have been too busy to finish this at work recently, I also do not have a Google license I can use for testing in my current job. I do believe the Python script is complete and working and it can be run by itself to act as a replacement for the Apple AirPort command. Can you indicate if you have tried the Python script by itself and did it work for you?

Once you have confirmed the Python script works for you I could create a beta release of 3.3 for you to then try and I can look to include your pushed update as well. It would be very helpful if you could then test that beta release and confirm if they work for you also.

Regarding the MunkiReport and MacAdmins Python compatibility issue.

I see that MunkiReport has been updated last year to actually require using the MacAdmins Python although it mentions that it does not support the latest MacAdmins version and recommends using the 3.10 version.

I have not tested that version with my Python script but would feel that it is likely to work with my script.

This is mentioned here - https://www.kevinmcox.com/2023/06/munkireport-python-3-and-php-8/ https://www.kevinmcox.com/2023/06/munkireport-python-3-and-php-8/ The link to the 3.10 version is here - https://github.com/macadmins/python/releases/tag/v3.10.9.80716 https://github.com/macadmins/python/releases/tag/v3.10.9.80716 I should be able to test 'downgrading' to that version of the MacAdmins Python and test that for you as well.

FYI - I don't currently run MunkiReport myself although I have plans to hopefully do so again so thanks for bringing this to my attention. Ironically, a different 'project' I have done is an AutoPkg recipe which would automate downloading the latest MacAdmins Python installer and adding it to Munki to keep my clients updated.

— Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2128345201, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VESPO6D3LRRIMQEF22DZD2MUVAVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRYGM2DKMRQGE. You are receiving this because you were mentioned.

jelockwood commented 1 month ago

@precursorca I am having a quick Look at some of your issues.

On a Mac which has Sonoma installed and already had the MacAdmins 3.12.1 python installed I ran the following two commands.

/usr/local/bin/managed_python3 --version (This as expected returns version 3.12.1)

/usr/local/bin/managed_python3 -m pip list (This as expected returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

For me typing the following in Terminal without sudo works

./pinpoint_scan.py

I then installed on the same Mac the 3.10.11 version of the MacAdmins python.

/usr/local/bin/managed_python3 --version (This as expected returns version 3.10.11)

/usr/local/bin/managed_python3 -m pip list (This also returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

I then ran the same ./pinpoint_scan.py command again without sudo and again it worked.

This seems to suggest that contrary to what you indicated 3.10.11 does include CoreWLAN although there is a possibility components previously installed via 3.12.1 have been kept and reused by 3.10.11.

Can you try the /usr/local/bin/managed_python3 -m pip list command yourself to see what your system shows?

Note: I have done a chmod +x pinpoint_scan.py on to my file

I have now also tried running my python script with sudo privileges and you are correct it fails. I see the error listed is as follows.

Unable to obtain location Services authorization, exiting

If we believe this error message - and I think it is reasonable to do so, then it maybe the following applies.

  1. I have given my normal user account permission to use Location Services for python
  2. This works for my (and your) accounts
  3. It could be this permission is a per user setting, to test this you should logout and then login as a second brand new user account and then try again, please let me know this result, check without making a change the status in this second user account of the Privacy & Security setting for location services to see if it shows location services as enabled for python
  4. If the second user account works and it is only root blocked, then it maybe due to the special nature of the root account Apple have imposed an extra block, if the second account fails and Privacy & Security show it is not yet enabled it is clearly a per user setting which will be very annoying. At this point I suspect and hope the former applies.

Possible workarounds

  1. As you have already indicated modify the shell script to run the python script as a logged in user and not root - the potential drawback is this means it will only work if a user is actually logged in
  2. Or create a special 'service' user account which could be marked as hidden from the login window, does not need admin level access and does not need to be a FileVault approved account, then have the shell script use that specific user account to run the python script (I have not tried this) this might work even when no user is logged in. This second user account will need to have a shell enabled even though in theory it is only running Python.
precursorca commented 1 month ago

VERY INTERESTING!

I installed Python 3.10 as soon as munkireport 5.8 suggested it would be necessary and the version available at the time was 3.10.9 !!

This is what is listed at https://github.com/munkireport/munkireport-php/wiki/How-to-Upgrade-Versions https://github.com/munkireport/munkireport-php/wiki/How-to-Upgrade-Versions

Version 3.10 of Mac Admins Python can be found on this page: https://github.com/macadmins/python/releases/tag/v3.10.9.80716 https://github.com/macadmins/python/releases/tag/v3.10.9.80716 I then tested it and downloaded and tested 3.10.11 -80742

Testing both revealed that they BOTH DO HAVE pyobjc-framework-CoreWLAN I originally missed this because I was looking for simply “CoreWLAN” listed alphabetically from “C” 9.0.1 in the case of 3.10.9 and 10.1 in the case of the most recent 3.10.11 80742

So it would appear my problem was not the version of python but rather the issue with the user.

Since I already have that python installed on all the clients I will test the code on a few computers with various users signed and let you know what I find out.


Alex Narvey @.***

On May 24, 2024, at 4:14 AM, jelockwood @.***> wrote:

@precursorca https://github.com/precursorca I am having a quick Look at some of your issues.

On a Mac which has Sonoma installed and already had the MacAdmins 3.12.1 python installed I ran the following two commands.

/usr/local/bin/managed_python3 --version (This as expected returns version 3.12.1)

/usr/local/bin/managed_python3 -m pip list (This as expected returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

For me typing the following in Terminal without sudo works

./pinpoint_scan.py

I then installed on the same Mac the 3.10.11 version of the MacAdmins python.

/usr/local/bin/managed_python3 --version (This as expected returns version 3.10.11)

/usr/local/bin/managed_python3 -m pip list (This also returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

I then ran the same ./pinpoint_scan.py command again without sudo and again it worked.

This seems to suggest that contrary to what you indicated 3.10.11 does include CoreWLAN although there is a possibility components previously installed via 3.12.1 have been kept and reused by 3.10.11.

Can you try the /usr/local/bin/managed_python3 -m pip list command yourself to see what your system shows?

Note: I have done a chmod +x pinpoint_scan.py on to my file

I have now also tried running my python script with sudo privileges and you are correct it fails. I see the error listed is as follows.

Unable to obtain location Services authorization, exiting

If we believe this error message - and I think it is reasonable to do so, then it maybe the following applies.

I have given my normal user account permission to use Location Services for python This works for my (and your) accounts It could be this permission is a per user setting, to test this you should logout and then login as a second brand new user account and then try again, please let me know this result, check without making a change the status in this second user account of the Privacy & Security setting for location services to see if it shows location services as enabled for python If the second user account works and it is only root blocked, then it maybe due to the special nature of the root account Apple have imposed an extra block, if the second account fails and Privacy & Security show it is not yet enabled it is clearly a per user setting which will be very annoying. At this point I suspect and hope the former applies. Possible workarounds

As you have already indicated modify the shell script to run the python script as a logged in user and not root - the potential drawback is this means it will only work if a user is actually logged in Or create a special 'service' user account which could be marked as hidden from the login window, does not need admin level access and does not need to be a FileVault approved account, then have the shell script use that specific user account to run the python script (I have not tried this) this might work even when no user is logged in. This second user account will need to have a shell enabled even though in theory it is only running Python. — Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2129034934, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEV6VRNBILDFS54Z3HTZD4AFVAVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRZGAZTIOJTGQ. You are receiving this because you were mentioned.

precursorca commented 1 month ago

Assuming we can get this all going the next big issue is going to be finding a graceful way to enable location services for python. I don’t think it can be done via MDM nor can it be done by command line. It would have to be done in the GUi on each device.

Ughhh.


Alex Narvey @.***

On May 24, 2024, at 5:50 AM, Alex Narvey @.***> wrote:

VERY INTERESTING!

I installed Python 3.10 as soon as munkireport 5.8 suggested it would be necessary and the version available at the time was 3.10.9 !!

This is what is listed at https://github.com/munkireport/munkireport-php/wiki/How-to-Upgrade-Versions

Version 3.10 of Mac Admins Python can be found on this page: https://github.com/macadmins/python/releases/tag/v3.10.9.80716

I then tested it and downloaded and tested 3.10.11 -80742

Testing both revealed that they BOTH DO HAVE pyobjc-framework-CoreWLAN I originally missed this because I was looking for simply “CoreWLAN” listed alphabetically from “C” 9.0.1 in the case of 3.10.9 and 10.1 in the case of the most recent 3.10.11 80742

So it would appear my problem was not the version of python but rather the issue with the user.

Since I already have that python installed on all the clients I will test the code on a few computers with various users signed and let you know what I find out.


Alex Narvey @. @.>

On May 24, 2024, at 4:14 AM, jelockwood @. @.>> wrote:

@precursorca https://github.com/precursorca I am having a quick Look at some of your issues.

On a Mac which has Sonoma installed and already had the MacAdmins 3.12.1 python installed I ran the following two commands.

/usr/local/bin/managed_python3 --version (This as expected returns version 3.12.1)

/usr/local/bin/managed_python3 -m pip list (This as expected returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

For me typing the following in Terminal without sudo works

./pinpoint_scan.py

I then installed on the same Mac the 3.10.11 version of the MacAdmins python.

/usr/local/bin/managed_python3 --version (This as expected returns version 3.10.11)

/usr/local/bin/managed_python3 -m pip list (This also returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

I then ran the same ./pinpoint_scan.py command again without sudo and again it worked.

This seems to suggest that contrary to what you indicated 3.10.11 does include CoreWLAN although there is a possibility components previously installed via 3.12.1 have been kept and reused by 3.10.11.

Can you try the /usr/local/bin/managed_python3 -m pip list command yourself to see what your system shows?

Note: I have done a chmod +x pinpoint_scan.py on to my file

I have now also tried running my python script with sudo privileges and you are correct it fails. I see the error listed is as follows.

Unable to obtain location Services authorization, exiting

If we believe this error message - and I think it is reasonable to do so, then it maybe the following applies.

I have given my normal user account permission to use Location Services for python This works for my (and your) accounts It could be this permission is a per user setting, to test this you should logout and then login as a second brand new user account and then try again, please let me know this result, check without making a change the status in this second user account of the Privacy & Security setting for location services to see if it shows location services as enabled for python If the second user account works and it is only root blocked, then it maybe due to the special nature of the root account Apple have imposed an extra block, if the second account fails and Privacy & Security show it is not yet enabled it is clearly a per user setting which will be very annoying. At this point I suspect and hope the former applies. Possible workarounds

As you have already indicated modify the shell script to run the python script as a logged in user and not root - the potential drawback is this means it will only work if a user is actually logged in Or create a special 'service' user account which could be marked as hidden from the login window, does not need admin level access and does not need to be a FileVault approved account, then have the shell script use that specific user account to run the python script (I have not tried this) this might work even when no user is logged in. This second user account will need to have a shell enabled even though in theory it is only running Python. — Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2129034934, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEV6VRNBILDFS54Z3HTZD4AFVAVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRZGAZTIOJTGQ. You are receiving this because you were mentioned.

jelockwood commented 1 month ago

Actually I believe I have found a method already. It would work roughly like the following. 1. The shell script is run, it runs the python script. The python script tries to use location services and fails. 2. A Jamf extension attribute checks and sees this, this triggers a Jamf policy to approve the location services via a shell script. So at least the first time the pinpoint script runs it will fail. I am not at my desk at the moment but can post the link later. It is currently written to approve MS Teams or Zoom but should be adaptable to the python runtime. It maybe this could be run without Jamf. Sent from my iPhoneOn 24 May 2024, at 15:47, Alex Narvey @.***> wrote: Assuming we can get this all going the next big issue is going to be finding a graceful way to enable location services for python.

I don’t think it can be done via MDM nor can it be done by command line.

It would have to be done in the GUi on each device.

Ughhh.


Alex Narvey

@.***

On May 24, 2024, at 5:50 AM, Alex Narvey @.***> wrote:

VERY INTERESTING!

I installed Python 3.10 as soon as munkireport 5.8 suggested it would be necessary and the version available at the time was 3.10.9 !!

This is what is listed at https://github.com/munkireport/munkireport-php/wiki/How-to-Upgrade-Versions

Version 3.10 of Mac Admins Python can be found on this page: https://github.com/macadmins/python/releases/tag/v3.10.9.80716

I then tested it and downloaded and tested 3.10.11 -80742

Testing both revealed that they BOTH DO HAVE pyobjc-framework-CoreWLAN

I originally missed this because I was looking for simply “CoreWLAN” listed alphabetically from “C”

9.0.1 in the case of 3.10.9

and 10.1 in the case of the most recent 3.10.11 80742

So it would appear my problem was not the version of python but rather the issue with the user.

Since I already have that python installed on all the clients I will test the code on a few computers with various users signed and let you know what I find out.


Alex Narvey

@. @.>

On May 24, 2024, at 4:14 AM, jelockwood @. @.>> wrote:

@precursorca https://github.com/precursorca

I am having a quick Look at some of your issues.

On a Mac which has Sonoma installed and already had the MacAdmins 3.12.1 python installed I ran the following two commands.

/usr/local/bin/managed_python3 --version

(This as expected returns version 3.12.1)

/usr/local/bin/managed_python3 -m pip list

(This as expected returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

For me typing the following in Terminal without sudo works

./pinpoint_scan.py

I then installed on the same Mac the 3.10.11 version of the MacAdmins python.

/usr/local/bin/managed_python3 --version

(This as expected returns version 3.10.11)

/usr/local/bin/managed_python3 -m pip list

(This also returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

I then ran the same ./pinpoint_scan.py command again without sudo and again it worked.

This seems to suggest that contrary to what you indicated 3.10.11 does include CoreWLAN although there is a possibility components previously installed via 3.12.1 have been kept and reused by 3.10.11.

Can you try the /usr/local/bin/managed_python3 -m pip list command yourself to see what your system shows?

Note: I have done a chmod +x pinpoint_scan.py on to my file

I have now also tried running my python script with sudo privileges and you are correct it fails. I see the error listed is as follows.

Unable to obtain location Services authorization, exiting

If we believe this error message - and I think it is reasonable to do so, then it maybe the following applies.

I have given my normal user account permission to use Location Services for python

This works for my (and your) accounts

It could be this permission is a per user setting, to test this you should logout and then login as a second brand new user account and then try again, please let me know this result, check without making a change the status in this second user account of the Privacy & Security setting for location services to see if it shows location services as enabled for python

If the second user account works and it is only root blocked, then it maybe due to the special nature of the root account Apple have imposed an extra block, if the second account fails and Privacy & Security show it is not yet enabled it is clearly a per user setting which will be very annoying. At this point I suspect and hope the former applies.

Possible workarounds

As you have already indicated modify the shell script to run the python script as a logged in user and not root - the potential drawback is this means it will only work if a user is actually logged in

Or create a special 'service' user account which could be marked as hidden from the login window, does not need admin level access and does not need to be a FileVault approved account, then have the shell script use that specific user account to run the python script (I have not tried this) this might work even when no user is logged in. This second user account will need to have a shell enabled even though in theory it is only running Python.

Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2129034934, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEV6VRNBILDFS54Z3HTZD4AFVAVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRZGAZTIOJTGQ.

You are receiving this because you were mentioned.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you modified the open/close state.Message ID: @.***>

precursorca commented 1 month ago

I do not have Jamf available. All computers are in Mosyle MDM and are using munki/munkireport


Alex Narvey @.***

On May 24, 2024, at 4:14 AM, jelockwood @.***> wrote:

@precursorca https://github.com/precursorca I am having a quick Look at some of your issues.

On a Mac which has Sonoma installed and already had the MacAdmins 3.12.1 python installed I ran the following two commands.

/usr/local/bin/managed_python3 --version (This as expected returns version 3.12.1)

/usr/local/bin/managed_python3 -m pip list (This as expected returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

For me typing the following in Terminal without sudo works

./pinpoint_scan.py

I then installed on the same Mac the 3.10.11 version of the MacAdmins python.

/usr/local/bin/managed_python3 --version (This as expected returns version 3.10.11)

/usr/local/bin/managed_python3 -m pip list (This also returns a list including the line pyobjc-framework-CoreWLAN 10.1 )

I then ran the same ./pinpoint_scan.py command again without sudo and again it worked.

This seems to suggest that contrary to what you indicated 3.10.11 does include CoreWLAN although there is a possibility components previously installed via 3.12.1 have been kept and reused by 3.10.11.

Can you try the /usr/local/bin/managed_python3 -m pip list command yourself to see what your system shows?

Note: I have done a chmod +x pinpoint_scan.py on to my file

I have now also tried running my python script with sudo privileges and you are correct it fails. I see the error listed is as follows.

Unable to obtain location Services authorization, exiting

If we believe this error message - and I think it is reasonable to do so, then it maybe the following applies.

I have given my normal user account permission to use Location Services for python This works for my (and your) accounts It could be this permission is a per user setting, to test this you should logout and then login as a second brand new user account and then try again, please let me know this result, check without making a change the status in this second user account of the Privacy & Security setting for location services to see if it shows location services as enabled for python If the second user account works and it is only root blocked, then it maybe due to the special nature of the root account Apple have imposed an extra block, if the second account fails and Privacy & Security show it is not yet enabled it is clearly a per user setting which will be very annoying. At this point I suspect and hope the former applies. Possible workarounds

As you have already indicated modify the shell script to run the python script as a logged in user and not root - the potential drawback is this means it will only work if a user is actually logged in Or create a special 'service' user account which could be marked as hidden from the login window, does not need admin level access and does not need to be a FileVault approved account, then have the shell script use that specific user account to run the python script (I have not tried this) this might work even when no user is logged in. This second user account will need to have a shell enabled even though in theory it is only running Python. — Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2129034934, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEV6VRNBILDFS54Z3HTZD4AFVAVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRZGAZTIOJTGQ. You are receiving this because you were mentioned.

jelockwood commented 1 month ago

@precursorca All Jamf is doing is automating running a shell script which runs as root. This is why I feel I should be possible to run locally or potentially via a different MDM. The script could even be wrapped in a pkg installer.

I found the link to the Jamf discussion, the script is basically reading and modifying a file. Full Disk access will be required for whatever process runs the script.

There are several versions of the script, scroll down to nearer the bottom to see newer versions. There is even potentially python version.

https://community.jamf.com/t5/jamf-pro/enable-location-services-on-a-per-app-basis-without-admin/m-p/278846

precursorca commented 1 month ago

The script on the page is to enable Location Services in toto; not to enable an apps specific location services. This still has to be toggled in the GUI as far as I can tell.

The other scripts from ginger scripting are to stop Home app from asking for location services so they are not germaine.


Alex Narvey @.***

On May 24, 2024, at 10:30 AM, jelockwood @.***> wrote:

@precursorca https://github.com/precursorca All Jamf is doing is automating running a shell script which runs as root. This is why I feel I should be possible to run locally or potentially via a different MDM. The script could even be wrapped in a pkg installer.

I found the link to the Jamf discussion, the script is basically reading and modifying a file. Full Disk access will be required for whatever process runs the script.

There are several versions of the script, scroll down to nearer the bottom to see newer versions. There is even potentially python version.

https://community.jamf.com/t5/jamf-pro/enable-location-services-on-a-per-app-basis-without-admin/m-p/278846

— Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2129826564, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEXL3XH7AOHFTPXAEKDZD5MK7AVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRZHAZDMNJWGQ. You are receiving this because you were mentioned.

precursorca commented 1 month ago

In my experimentation you can use

sudo defaults read /var/db/locationd/clients.plist

To read the list of apps that are listed in the GUI and determine if they are enable or not. But whether you can toggle on the Authorized bit by command line without blowing things up I do not know.

Python location services on

"6550F213-F269-4324-B7B6-2A61E436EEB9:iorg.python.python:" = { Authorized = 1; BundleId = "org.python.python"; BundlePath = "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.10/Resources/Python.app"; ClientStorageToken = {length = 32, bytes = 0xda3b9c9c dbed5c62 7a77a0ff 3561e776 ... 5d01ee96 5e401594 }; Executable = "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.10/Resources/Python.app/Contents/MacOS/Python"; LocationTimeStopped = "738251179.871581"; PluginBundleIds = ( ); ReceivingLocationInformationTimeStopped = "738251178.566563"; Registered = 1; Requirement = "identifier \"org.python.python\" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] / exists / and certificate leaf[field.1.2.840.113635.100.6.1.13] / exists / and certificate leaf[subject.OU] = \"9GQZ7KUFR6\""; };

Python locations services off

"6550F213-F269-4324-B7B6-2A61E436EEB9:iorg.python.python:" = { Authorized = 0; BundleId = "org.python.python"; BundlePath = "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.10/Resources/Python.app"; ClientStorageToken = {length = 32, bytes = 0xda3b9c9c dbed5c62 7a77a0ff 3561e776 ... 5d01ee96 5e401594 }; Executable = "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.10/Resources/Python.app/Contents/MacOS/Python"; LocationTimeStopped = "738251179.871581"; PluginBundleIds = ( ); ReceivingLocationInformationTimeStopped = "738251178.566563"; Registered = 1; Requirement = "identifier \"org.python.python\" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] / exists / and certificate leaf[field.1.2.840.113635.100.6.1.13] / exists / and certificate leaf[subject.OU] = \"9GQZ7KUFR6\""; };


Alex Narvey @.***

On May 24, 2024, at 10:47 AM, Alex Narvey @.***> wrote:

The script on the page is to enable Location Services in toto; not to enable an apps specific location services. This still has to be toggled in the GUI as far as I can tell.

The other scripts from ginger scripting are to stop Home app from asking for location services so they are not germaine.


Alex Narvey @.***

On May 24, 2024, at 10:30 AM, jelockwood @.***> wrote:

@precursorca https://github.com/precursorca All Jamf is doing is automating running a shell script which runs as root. This is why I feel I should be possible to run locally or potentially via a different MDM. The script could even be wrapped in a pkg installer.

I found the link to the Jamf discussion, the script is basically reading and modifying a file. Full Disk access will be required for whatever process runs the script.

There are several versions of the script, scroll down to nearer the bottom to see newer versions. There is even potentially python version.

https://community.jamf.com/t5/jamf-pro/enable-location-services-on-a-per-app-basis-without-admin/m-p/278846

— Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2129826564, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEXL3XH7AOHFTPXAEKDZD5MK7AVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRZHAZDMNJWGQ. You are receiving this because you were mentioned.

precursorca commented 1 month ago

I have found that you can get the state of python’s authorization to location services but you cannot edit it by command line. The client.plist is protected by SIP. The best you could hope to do I think is determine if access is false and pop up a dialog with a picture in it to show the user how to enable it.

But while doing all this I came across locationator. https://github.com/RhetTbull/locationator RhetTbull/locationator: A simple macOS menubar app that provides access to the macOS Location Services reverse geocoding API via a local web server as well as a command line tool. github.com

Installing Locationator and enabling that for location services would avoid all this google API and payments. The Macs own location service seems to be dead accurate at giving lat and longitude and locationator allows you to reverse geo that in the command line.

Here’s a bash script for locationator that outputs amazingly detailed address info. In this example I reverse geoed the coordinates for Apple Park (but if you do it for a house it can give you street address in the name key):

{"location": [37.334886, -122.008988], "name": "Apple Park", "thoroughfare": "Apple Park Way", "subThoroughfare": "1", "locality": "Cupertino", "subLocality": "", "administrativeArea": "CA", "subAdministrativeArea": "Santa Clara County", "postalCode": "95014", "ISOcountryCode": "US", "country": "United States", "postalAddress": {"street": "1 Apple Park Way", "city": "Cupertino", "state": "CA", "country": "United States", "postalCode": "95014", "ISOCountryCode": "US", "subAdministrativeArea": "Santa Clara County", "subLocality": ""}, "inlandWater": "", "ocean": "", "areasOfInterest": ["Apple Park"], "timeZoneName": "America/Los_Angeles", "timeZoneAbbreviation": "PDT", "timeZoneSecondsFromGMT": -25200}

!/bin/bash

GEODATA=$( curl -X GET http://localhost:8000/current_location )

read -r -d '' JXA <<EOF function run() { var ipinfo = JSON.parse(`$GEODATA`); return ipinfo.latitude; } EOF

read -r -d '' JXB <<EOF function run() { var ipinfo = JSON.parse(`$GEODATA`); return ipinfo.longitude; } EOF

LATITUDE=$( osascript -l 'JavaScript' <<< "${JXA}" ) LONGITUDE=$( osascript -l 'JavaScript' <<< "${JXB}" )

echo "The Latitude is ${LATITUDE}" echo "The Longitude is ${LONGITUDE}"

curl -X GET "http://localhost:8000/reverse_geocode?latitude=${LATITUDE}&longitude=${LONGITUDE}”


Alex Narvey @.***

On May 24, 2024, at 11:01 AM, Alex Narvey @.***> wrote:

In my experimentation you can use

sudo defaults read /var/db/locationd/clients.plist

To read the list of apps that are listed in the GUI and determine if they are enable or not. But whether you can toggle on the Authorized bit by command line without blowing things up I do not know.

Python location services on

"6550F213-F269-4324-B7B6-2A61E436EEB9:iorg.python.python:" = { Authorized = 1; BundleId = "org.python.python"; BundlePath = "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.10/Resources/Python.app"; ClientStorageToken = {length = 32, bytes = 0xda3b9c9c dbed5c62 7a77a0ff 3561e776 ... 5d01ee96 5e401594 }; Executable = "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.10/Resources/Python.app/Contents/MacOS/Python"; LocationTimeStopped = "738251179.871581"; PluginBundleIds = ( ); ReceivingLocationInformationTimeStopped = "738251178.566563"; Registered = 1; Requirement = "identifier \"org.python.python\" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] / exists / and certificate leaf[field.1.2.840.113635.100.6.1.13] / exists / and certificate leaf[subject.OU] = \"9GQZ7KUFR6\""; };

Python locations services off

"6550F213-F269-4324-B7B6-2A61E436EEB9:iorg.python.python:" = { Authorized = 0; BundleId = "org.python.python"; BundlePath = "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.10/Resources/Python.app"; ClientStorageToken = {length = 32, bytes = 0xda3b9c9c dbed5c62 7a77a0ff 3561e776 ... 5d01ee96 5e401594 }; Executable = "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.10/Resources/Python.app/Contents/MacOS/Python"; LocationTimeStopped = "738251179.871581"; PluginBundleIds = ( ); ReceivingLocationInformationTimeStopped = "738251178.566563"; Registered = 1; Requirement = "identifier \"org.python.python\" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] / exists / and certificate leaf[field.1.2.840.113635.100.6.1.13] / exists / and certificate leaf[subject.OU] = \"9GQZ7KUFR6\""; };


Alex Narvey @.***

On May 24, 2024, at 10:47 AM, Alex Narvey @.***> wrote:

The script on the page is to enable Location Services in toto; not to enable an apps specific location services. This still has to be toggled in the GUI as far as I can tell.

The other scripts from ginger scripting are to stop Home app from asking for location services so they are not germaine.


Alex Narvey @.***

On May 24, 2024, at 10:30 AM, jelockwood @.***> wrote:

@precursorca https://github.com/precursorca All Jamf is doing is automating running a shell script which runs as root. This is why I feel I should be possible to run locally or potentially via a different MDM. The script could even be wrapped in a pkg installer.

I found the link to the Jamf discussion, the script is basically reading and modifying a file. Full Disk access will be required for whatever process runs the script.

There are several versions of the script, scroll down to nearer the bottom to see newer versions. There is even potentially python version.

https://community.jamf.com/t5/jamf-pro/enable-location-services-on-a-per-app-basis-without-admin/m-p/278846

— Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2129826564, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEXL3XH7AOHFTPXAEKDZD5MK7AVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRZHAZDMNJWGQ. You are receiving this because you were mentioned.

jelockwood commented 1 month ago

@precursorca

Your info about Locationator is interesting. I can see it could work but has some of its own drawbacks.

  1. It only works if a user is logged in
  2. It has to be launched at least once by the user via 'Option open'
  3. User has to be relied on to make sure it thereafter runs every time

So it seems even more manual than my solution. Some of the above could be worked around if you built and signed your own copy, as it is open source this should be possible. You might even be able to automate auto launching as standard.

The articles and scripts I provided a link to on the JAMF forum do describe how to successfully enable Location Services. Those discussions also state they work even in macOS Sonoma.

I know you do not use Jamf but you could look at using the same approach via either Mosyle or some other method.

In the case of Pinpoint and therefore more specifically in the case of Python the following need to be done.

  1. Run my pinpoint_scan.py script at least once, this creates an entry in the /var/db/locationd/clients.plist file
  2. As you indicated and I believe I referred to, whilst this can be read, due to SIP modifying it is restricted, you will therefore need to grant a process Full Disk Access so it has permission to modify this. In the case of Jamf Pro it gives its own agent this permission anyway via a PPPC profile, so Jamf can then run scripts which uses this permission and can hence modify this file. Again you will have to find your own equivalent to this.
  3. Via whatever process you use, run a version of the following script which has been modified from the examples in the Jamf discussion to grant Python location services permission
  4. Then, the next time the pinpoint_scan.py script is run it will have permission to use Location Services and will succeed.
#!/bin/bash

####################################################################################################
# DESC:  When the script runs, it will make a copy of the existing location services
#   /var/db/locationd/client.plist to be used in case a revert is needed. Following, we swap 0's
#   to 1's within the client.plist for Teams and Teams helper to enable them. 
# REFS:   N/A
#
# Author: Bill Addis
#
# HISTORY
#   - v.0.0: discovery of appropriate directories and files for manipulation
#   - v.1.0:  initial script upload
#   - v.1.1:    added additional logging, as well as error checking to ensure the plist exists before manipulation
#   - v.1.1:    discovered+fixed a bug where if an end-user manually DISABLES Teams from using location services, the "authorized key" disappears and cannot be set
#   - v.1.2: Adding an initial check at the top to see if location services for MacOS are enabled
#   - v.1.3: Updated to account for changes in macOS Ventura
#   - v.1.5 Bill Addis, Sep 15, 2023: Added for loop to update all Teams location entries (old Teams and new)
#   - v.1.6 Bill Addis, Oct 23, 2023: Added support for Sonoma. Updated script to loop for all Teams versions
#   - v.1.7: Julian Ortega, Dec 20, 2023: Updated to work for generic apps instead of MS Teams
####################################################################################################
# This version modified to instead default to granting Python permission
scriptVersion="2023.12.2"
scriptLog="${4:-"/var/log/com.jamf.appLocationServices.log"}"
appName="${5:-"Python"}"
appIdentifier="${6:-"org.python.python"}"

function updateScriptLog() {
    echo -e "$( date +%Y-%m-%d\ %H:%M:%S ) - ${1}" | tee -a "${scriptLog}"
}

updateScriptLog "SCRIPT VERSION: $scriptVersion"

if [[ ! -f "${scriptLog}" ]]; then
    touch "${scriptLog}"
fi

# Set line debugging
PS4='Line ${LINENO}: '

# updateScriptLog mount point in Jamf
updateScriptLog $1

# Is location services enabled? 
location_enabled=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled)
if [[ "$location_enabled" = "1" ]]; then
    updateScriptLog "Location Services are enabled, moving on..."
else
    updateScriptLog "Location Services disabled. Enabling them..."
# UPDATE THIS LINE TO ACTUALLY ENABLE LOCATION SERVICES
    jamf policy -event location
    sleep 3
    location_enabled=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled)
    if [[ "$location_enabled" = "0" ]]; then
        updateScriptLog "Unable to enable location services...exiting"
        exit 1
    fi
fi

# Does the clients.plist exist?
updateScriptLog "Current contents of /var/db/locationd directory:"
updateScriptLog "$(ls /var/db/locationd)"

osVers=$(sw_vers -productVersion)
updateScriptLog "macOS $osVers currently installed."

if [[ "$osVers" == *13* ]] ; then
updateScriptLog "Executing for macOS Ventura..."
clients="/var/db/locationd/clients.plist"
    if [[ -f "$clients" ]]; then
        key1=$(/usr/libexec/PlistBuddy -c "Print" /var/db/locationd/clients.plist | grep :$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}' | head -1)
        updateScriptLog "$clients already exists! Moving on..."
        updateScriptLog "Current key values for $appName app"
        updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $key1" $clients)"
        updateScriptLog "================================="

        # Create a backup of the existing client location services file
        cp $clients /var/db/locationd/clients.BAK

        # Create an extra working backup
        cp $clients /private/var/tmp/

        # Convert our working backup client plist to xml for editing
        plutil -convert xml1 /private/var/tmp/clients.plist

        count=1

        for i in $(/usr/libexec/PlistBuddy -c "Print" /private/var/tmp/clients.plist | grep :$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}');

            do
            updateScriptLog "Current key value for key$count:"
            updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $i" $clients)"

            # Use Plist Buddy to mark-up client plist, enabling app's location services
            /usr/LibExec/PlistBuddy -c "Set :$i:Authorized true" /private/var/tmp/clients.plist
            # Check return for last command
            if [[ "$?" = "1" ]]; then
                updateScriptLog "Authorized key seems to be missing...re-adding the key"
                /usr/LibExec/PlistBuddy -c "Add :$i:Authorized bool true" /private/var/tmp/clients.plist
                updateScriptLog "Adding 'authorized' key for $i location services returned: $?"
            fi
            updateScriptLog "Setting $i location services returned: $?"

            ((count=count+1))
            done

        # Convert back to binary
        plutil -convert binary1 /private/var/tmp/clients.plist

        # Put the updated client plist into appropriate dir
        cp /private/var/tmp/clients.plist $clients

        # Kill and restart the location services daemon and remove our temp file
        killall locationd
        rm /private/var/tmp/clients.plist
    else
        updateScriptLog "$clients does not exist...exiting"
        exit 1
    fi
elif [[ "$osVers" == *12* ]] ; then
    updateScriptLog "Executing for macOS 12 or less..."
    clients="/var/db/locationd/clients.plist"
    if [[ -f "$clients" ]]; then
        updateScriptLog "$clients already exists! Moving on..."
        updateScriptLog "Current key values for $appName app:"
        updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print :$appIdentifier" $clients)"
        updateScriptLog "================================="

        # Create a backup of the existing client location services file
        cp $clients /var/db/locationd/clients.BAK

        # Create an extra working backup
        cp $clients /private/var/tmp/

        # Convert our working backup client plist to xml for editing
        plutil -convert xml1 /private/var/tmp/clients.plist

        # Use Plist Buddy to mark-up client plist, enabling app's location services
        /usr/LibExec/PlistBuddy -c "Set :com.$appIdentifier:Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            updateScriptLog "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :$appIdentifier:Authorized bool true" /private/var/tmp/clients.plist
            updateScriptLog "Adding 'authorized' key for $appName app location services returned: $?"
            #/usr/LibExec/PlistBuddy -c "Set :$appIdentifier:Authorized true" /private/var/tmp/clients.plist
        fi
        updateScriptLog "Setting $appName app location services returned: $?"

        # Convert back to binary
        plutil -convert binary1 /private/var/tmp/clients.plist

        # Put the updated client plist into appropriate dir
        cp /private/var/tmp/clients.plist $clients

        # Kill and restart the location services daemon and remove our temp file
        killall locationd
        rm /private/var/tmp/clients.plist
    else
        updateScriptLog "$clients does not exist...exiting"
        exit 1
    fi
elif [[ "$osVers" == *14* ]] ; then
    updateScriptLog "Executing for macOS 14 Sonoma..."
    clients="/var/db/locationd/clients.plist"
        if [[ -f "$clients" ]]; then
            updateScriptLog "$clients already exists! Moving on..."

            # Create a backup of the existing client location services file
            cp $clients /var/db/locationd/clients.BAK

            # Create an extra working backup
            cp $clients /private/var/tmp/

            # Convert our working backup client plist to xml for editing
            plutil -convert xml1 /private/var/tmp/clients.plist

            count=1

            for i in $(/usr/libexec/PlistBuddy -c "Print" /private/var/tmp/clients.plist | grep -a :i$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}'  | sed "s/..$//");

            do
            updateScriptLog "Current key value for key$count:"
            updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $i" $clients)"

            # Use Plist Buddy to mark-up client plist, enabling app's location services
            /usr/LibExec/PlistBuddy -c "Set :$i\::Authorized true" /private/var/tmp/clients.plist
            # Check return for last command
            if [[ "$?" = "1" ]]; then
                updateScriptLog "Authorized key seems to be missing...re-adding the key"
                /usr/LibExec/PlistBuddy -c "Add :$i\::Authorized bool true" /private/var/tmp/clients.plist
                updateScriptLog "Adding 'authorized' key for $i location services returned: $?"
            fi
            updateScriptLog "Setting $i location services returned: $?"

            ((count=count+1))
            done

            # Convert back to binary
            plutil -convert binary1 /private/var/tmp/clients.plist

            # Put the updated client plist into appropriate dir
            cp /private/var/tmp/clients.plist $clients

            # Kill and restart the location services daemon and remove our temp file
            killall locationd
            #rm /private/var/tmp/clients.plist
        else
            updateScriptLog "$clients does not exist...exiting"
            exit 1
        fi
fi
# Display the final return code 
exit $?

Obviously manually granting permission is another approach but I would agree not acceptable.

Note: Apple have over the years made this and other similar things much harder and sadly will continue to do so. Sonoma made it even more difficult. Pinpoint 1 not written by me used the built-in Apple API which Apple since effectively blocked. I wrote my replacement version to use the Google API originally when the Google API was completely free and had to update it to work with the paid access. I have here now most of the pieces to do it in Sonoma via my python script although enabling Location Services is now the new issue. Who knows what Apple will do next.

precursorca commented 1 month ago

My script didn’t work because I needed to grant Fill Disk Access to Terminal. This is also required for the Bill Addis script to work.

You are correct, the locationator app is a web server that needs to be running in a user environment before it can be queried.


Alex Narvey @.***

On May 25, 2024, at 11:28 AM, jelockwood @.***> wrote:

@precursorca https://github.com/precursorca Your info about Locationator is interesting. I can see it could work but has some of its own drawbacks.

It only works if a user is logged in It has to be launched at least once by the user via 'Option open' User has to be relied on to make sure it thereafter runs every time So it seems even more manual than my solution. Some of the above could be worked around if you built and signed your own copy, as it is open source this should be possible. You might even be able to automate auto launching as standard.

The articles and scripts I provided a link to on the JAMF forum do describe how to successfully enable Location Services. Those discussions also state they work even in macOS Sonoma.

I know you do not use Jamf but you could look at using the same approach via either Mosyle or some other method.

In the case of Pinpoint and therefore more specifically in the case of Python the following need to be done.

Run my pinpoint_scan.py script at least once, this creates an entry in the /var/db/locationd/clients.plist file As you indicated and I believe I referred to, whilst this can be read, due to SIP modifying it is restricted, you will therefore need to grant a process Full Disk Access so it has permission to modify this. In the case of Jamf Pro it gives its own agent this permission anyway via a PPPC profile, so Jamf can then run scripts which uses this permission and can hence modify this file. Again you will have to find your own equivalent to this. Via whatever process you use, run a version of the following script which has been modified from the examples in the Jamf discussion to grant Python location services permission Then, the next time the pinpoint_scan.py script is run it will have permission to use Location Services and will succeed.

!/bin/bash

####################################################################################################

DESC: When the script runs, it will make a copy of the existing location services

/var/db/locationd/client.plist to be used in case a revert is needed. Following, we swap 0's

to 1's within the client.plist for Teams and Teams helper to enable them.

REFS: N/A

#

Author: Bill Addis

#

HISTORY

- v.0.0: discovery of appropriate directories and files for manipulation

- v.1.0: initial script upload

- v.1.1: added additional logging, as well as error checking to ensure the plist exists before manipulation

- v.1.1: discovered+fixed a bug where if an end-user manually DISABLES Teams from using location services, the "authorized key" disappears and cannot be set

- v.1.2: Adding an initial check at the top to see if location services for MacOS are enabled

- v.1.3: Updated to account for changes in macOS Ventura

- v.1.5 Bill Addis, Sep 15, 2023: Added for loop to update all Teams location entries (old Teams and new)

- v.1.6 Bill Addis, Oct 23, 2023: Added support for Sonoma. Updated script to loop for all Teams versions

- v.1.7: Julian Ortega, Dec 20, 2023: Updated to work for generic apps instead of MS Teams

####################################################################################################

This version modified to instead default to granting Python permission

scriptVersion="2023.12.2" scriptLog="${4:-"/var/log/com.jamf.appLocationServices.log"}" appName="${5:-"Python"}" appIdentifier="${6:-"org.python.python"}"

function updateScriptLog() { echo -e "$( date +%Y-%m-%d\ %H:%M:%S ) - ${1}" | tee -a "${scriptLog}" }

updateScriptLog "SCRIPT VERSION: $scriptVersion"

if [[ ! -f "${scriptLog}" ]]; then touch "${scriptLog}" fi

Set line debugging

PS4='Line ${LINENO}: '

updateScriptLog mount point in Jamf

updateScriptLog $1

Is location services enabled?

location_enabled=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled) if [[ "$location_enabled" = "1" ]]; then updateScriptLog "Location Services are enabled, moving on..." else updateScriptLog "Location Services disabled. Enabling them..."

UPDATE THIS LINE TO ACTUALLY ENABLE LOCATION SERVICES

jamf policy -event location
sleep 3

location_enabled=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled) if [[ "$location_enabled" = "0" ]]; then updateScriptLog "Unable to enable location services...exiting" exit 1 fi fi

Does the clients.plist exist?

updateScriptLog "Current contents of /var/db/locationd directory:" updateScriptLog "$(ls /var/db/locationd)"

osVers=$(sw_vers -productVersion) updateScriptLog "macOS $osVers currently installed."

if [[ "$osVers" == 13 ]] ; then updateScriptLog "Executing for macOS Ventura..." clients="/var/db/locationd/clients.plist" if [[ -f "$clients" ]]; then key1=$(/usr/libexec/PlistBuddy -c "Print" /var/db/locationd/clients.plist | grep :$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\:");print $1}' | head -1) updateScriptLog "$clients already exists! Moving on..." updateScriptLog "Current key values for $appName app" updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $key1" $clients)" updateScriptLog "================================="

    # Create a backup of the existing client location services file
    cp $clients /var/db/locationd/clients.BAK

    # Create an extra working backup
    cp $clients /private/var/tmp/

    # Convert our working backup client plist to xml for editing
    plutil -convert xml1 /private/var/tmp/clients.plist

    count=1

    for i in $(/usr/libexec/PlistBuddy -c "Print" /private/var/tmp/clients.plist | grep :$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}');

        do
        updateScriptLog "Current key value for key$count:"
        updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $i" $clients)"

        # Use Plist Buddy to mark-up client plist, enabling app's location services
        /usr/LibExec/PlistBuddy -c "Set :$i:Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            updateScriptLog "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :$i:Authorized bool true" /private/var/tmp/clients.plist
            updateScriptLog "Adding 'authorized' key for $i location services returned: $?"
        fi
        updateScriptLog "Setting $i location services returned: $?"

        ((count=count+1))
        done

    # Convert back to binary
    plutil -convert binary1 /private/var/tmp/clients.plist

    # Put the updated client plist into appropriate dir
    cp /private/var/tmp/clients.plist $clients

    # Kill and restart the location services daemon and remove our temp file
    killall locationd
    rm /private/var/tmp/clients.plist
else
    updateScriptLog "$clients does not exist...exiting"
    exit 1
fi

elif [[ "$osVers" == 12 ]] ; then updateScriptLog "Executing for macOS 12 or less..." clients="/var/db/locationd/clients.plist" if [[ -f "$clients" ]]; then updateScriptLog "$clients already exists! Moving on..." updateScriptLog "Current key values for $appName app:" updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print :$appIdentifier" $clients)" updateScriptLog "================================="

    # Create a backup of the existing client location services file
    cp $clients /var/db/locationd/clients.BAK

    # Create an extra working backup
    cp $clients /private/var/tmp/

    # Convert our working backup client plist to xml for editing
    plutil -convert xml1 /private/var/tmp/clients.plist

    # Use Plist Buddy to mark-up client plist, enabling app's location services
    /usr/LibExec/PlistBuddy -c "Set :com.$appIdentifier:Authorized true" /private/var/tmp/clients.plist
    # Check return for last command
    if [[ "$?" = "1" ]]; then
        updateScriptLog "Authorized key seems to be missing...re-adding the key"
        /usr/LibExec/PlistBuddy -c "Add :$appIdentifier:Authorized bool true" /private/var/tmp/clients.plist
        updateScriptLog "Adding 'authorized' key for $appName app location services returned: $?"
        #/usr/LibExec/PlistBuddy -c "Set :$appIdentifier:Authorized true" /private/var/tmp/clients.plist
    fi
    updateScriptLog "Setting $appName app location services returned: $?"

    # Convert back to binary
    plutil -convert binary1 /private/var/tmp/clients.plist

    # Put the updated client plist into appropriate dir
    cp /private/var/tmp/clients.plist $clients

    # Kill and restart the location services daemon and remove our temp file
    killall locationd
    rm /private/var/tmp/clients.plist
else
    updateScriptLog "$clients does not exist...exiting"
    exit 1
fi

elif [[ "$osVers" == 14 ]] ; then updateScriptLog "Executing for macOS 14 Sonoma..." clients="/var/db/locationd/clients.plist" if [[ -f "$clients" ]]; then updateScriptLog "$clients already exists! Moving on..."

        # Create a backup of the existing client location services file
        cp $clients /var/db/locationd/clients.BAK

        # Create an extra working backup
        cp $clients /private/var/tmp/

        # Convert our working backup client plist to xml for editing
        plutil -convert xml1 /private/var/tmp/clients.plist

        count=1

        for i in $(/usr/libexec/PlistBuddy -c "Print" /private/var/tmp/clients.plist | grep -a :i$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}'  | sed "s/..$//");

        do
        updateScriptLog "Current key value for key$count:"
        updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $i" $clients)"

        # Use Plist Buddy to mark-up client plist, enabling app's location services
        /usr/LibExec/PlistBuddy -c "Set :$i\::Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            updateScriptLog "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :$i\::Authorized bool true" /private/var/tmp/clients.plist
            updateScriptLog "Adding 'authorized' key for $i location services returned: $?"
        fi
        updateScriptLog "Setting $i location services returned: $?"

        ((count=count+1))
        done

        # Convert back to binary
        plutil -convert binary1 /private/var/tmp/clients.plist

        # Put the updated client plist into appropriate dir
        cp /private/var/tmp/clients.plist $clients

        # Kill and restart the location services daemon and remove our temp file
        killall locationd
        #rm /private/var/tmp/clients.plist
    else
        updateScriptLog "$clients does not exist...exiting"
        exit 1
    fi

fi

Display the final return code

exit $? Obviously manually granting permission is another approach but I would agree not acceptable.

Note: Apple have over the years made this and other similar things much harder and sadly will continue to do so. Sonoma made it even more difficult. Pinpoint 1 not written by me used the built-in Apple API which Apple since effectively blocked. I wrote my replacement version to use the Google API originally when the Google API was completely free and had to update it to work with the paid access. I have here now most of the pieces to do it in Sonoma via my python script although enabling Location Services is now the new issue. Who knows what Apple will do next.

— Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2131339802, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEUWEJQ636B4WXOKNCDZEC32TAVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMZRGMZTSOBQGI. You are receiving this because you were mentioned.

precursorca commented 1 month ago

I now have it installing from munki (including enabling the location services) and working properly on computers with macOS 14.4.1 or higher.

I had to first deliver the following as Security and Privacy profiles from Mosyle MDM: Terminal - allow Full disk Access Munki - Allow Full Disk Access Munki - Allow App Management

There was a slight correction I made to the pinpoint.sh to include some lines in the macOS 14 section specifically to run the pinpoint_scan.py as user.

And also I had to deliver the Bill Addis script in the pkg so that my munki post install script could enable location services. I called that script: GrantPythonLocationServiceAccess.sh and made minor edits to it to avoid errors.

Then I wrapped it all up using munkipkg and delivered it via munki with a post install script that forces a scan to get python into location services and then enables the location services before setting up the pinpoint prefs and optimication and running pinpoint.

I am currently delivering it to my computers as 3.2.7.4 I put all these files into my clone of your repo so that you could examine them if you like.

https://github.com/precursorca/pinpoint/tree/master precursorca/pinpoint: A script for finding your Mac github.com


Alex Narvey @.***

On May 25, 2024, at 3:01 PM, Alex Narvey @.***> wrote:

My script didn’t work because I needed to grant Fill Disk Access to Terminal. This is also required for the Bill Addis script to work.

You are correct, the locationator app is a web server that needs to be running in a user environment before it can be queried.


Alex Narvey @.***

On May 25, 2024, at 11:28 AM, jelockwood @.***> wrote:

@precursorca https://github.com/precursorca Your info about Locationator is interesting. I can see it could work but has some of its own drawbacks.

It only works if a user is logged in It has to be launched at least once by the user via 'Option open' User has to be relied on to make sure it thereafter runs every time So it seems even more manual than my solution. Some of the above could be worked around if you built and signed your own copy, as it is open source this should be possible. You might even be able to automate auto launching as standard.

The articles and scripts I provided a link to on the JAMF forum do describe how to successfully enable Location Services. Those discussions also state they work even in macOS Sonoma.

I know you do not use Jamf but you could look at using the same approach via either Mosyle or some other method.

In the case of Pinpoint and therefore more specifically in the case of Python the following need to be done.

Run my pinpoint_scan.py script at least once, this creates an entry in the /var/db/locationd/clients.plist file As you indicated and I believe I referred to, whilst this can be read, due to SIP modifying it is restricted, you will therefore need to grant a process Full Disk Access so it has permission to modify this. In the case of Jamf Pro it gives its own agent this permission anyway via a PPPC profile, so Jamf can then run scripts which uses this permission and can hence modify this file. Again you will have to find your own equivalent to this. Via whatever process you use, run a version of the following script which has been modified from the examples in the Jamf discussion to grant Python location services permission Then, the next time the pinpoint_scan.py script is run it will have permission to use Location Services and will succeed.

!/bin/bash

####################################################################################################

DESC: When the script runs, it will make a copy of the existing location services

/var/db/locationd/client.plist to be used in case a revert is needed. Following, we swap 0's

to 1's within the client.plist for Teams and Teams helper to enable them.

REFS: N/A

#

Author: Bill Addis

#

HISTORY

- v.0.0: discovery of appropriate directories and files for manipulation

- v.1.0: initial script upload

- v.1.1: added additional logging, as well as error checking to ensure the plist exists before manipulation

- v.1.1: discovered+fixed a bug where if an end-user manually DISABLES Teams from using location services, the "authorized key" disappears and cannot be set

- v.1.2: Adding an initial check at the top to see if location services for MacOS are enabled

- v.1.3: Updated to account for changes in macOS Ventura

- v.1.5 Bill Addis, Sep 15, 2023: Added for loop to update all Teams location entries (old Teams and new)

- v.1.6 Bill Addis, Oct 23, 2023: Added support for Sonoma. Updated script to loop for all Teams versions

- v.1.7: Julian Ortega, Dec 20, 2023: Updated to work for generic apps instead of MS Teams

####################################################################################################

This version modified to instead default to granting Python permission

scriptVersion="2023.12.2" scriptLog="${4:-"/var/log/com.jamf.appLocationServices.log"}" appName="${5:-"Python"}" appIdentifier="${6:-"org.python.python"}"

function updateScriptLog() { echo -e "$( date +%Y-%m-%d\ %H:%M:%S ) - ${1}" | tee -a "${scriptLog}" }

updateScriptLog "SCRIPT VERSION: $scriptVersion"

if [[ ! -f "${scriptLog}" ]]; then touch "${scriptLog}" fi

Set line debugging

PS4='Line ${LINENO}: '

updateScriptLog mount point in Jamf

updateScriptLog $1

Is location services enabled?

location_enabled=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled) if [[ "$location_enabled" = "1" ]]; then updateScriptLog "Location Services are enabled, moving on..." else updateScriptLog "Location Services disabled. Enabling them..."

UPDATE THIS LINE TO ACTUALLY ENABLE LOCATION SERVICES

jamf policy -event location
sleep 3

location_enabled=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled) if [[ "$location_enabled" = "0" ]]; then updateScriptLog "Unable to enable location services...exiting" exit 1 fi fi

Does the clients.plist exist?

updateScriptLog "Current contents of /var/db/locationd directory:" updateScriptLog "$(ls /var/db/locationd)"

osVers=$(sw_vers -productVersion) updateScriptLog "macOS $osVers currently installed."

if [[ "$osVers" == 13 ]] ; then updateScriptLog "Executing for macOS Ventura..." clients="/var/db/locationd/clients.plist" if [[ -f "$clients" ]]; then key1=$(/usr/libexec/PlistBuddy -c "Print" /var/db/locationd/clients.plist | grep :$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\:");print $1}' | head -1) updateScriptLog "$clients already exists! Moving on..." updateScriptLog "Current key values for $appName app" updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $key1" $clients)" updateScriptLog "================================="

    # Create a backup of the existing client location services file
    cp $clients /var/db/locationd/clients.BAK

    # Create an extra working backup
    cp $clients /private/var/tmp/

    # Convert our working backup client plist to xml for editing
    plutil -convert xml1 /private/var/tmp/clients.plist

    count=1

    for i in $(/usr/libexec/PlistBuddy -c "Print" /private/var/tmp/clients.plist | grep :$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}');

        do
        updateScriptLog "Current key value for key$count:"
        updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $i" $clients)"

        # Use Plist Buddy to mark-up client plist, enabling app's location services
        /usr/LibExec/PlistBuddy -c "Set :$i:Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            updateScriptLog "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :$i:Authorized bool true" /private/var/tmp/clients.plist
            updateScriptLog "Adding 'authorized' key for $i location services returned: $?"
        fi
        updateScriptLog "Setting $i location services returned: $?"

        ((count=count+1))
        done

    # Convert back to binary
    plutil -convert binary1 /private/var/tmp/clients.plist

    # Put the updated client plist into appropriate dir
    cp /private/var/tmp/clients.plist $clients

    # Kill and restart the location services daemon and remove our temp file
    killall locationd
    rm /private/var/tmp/clients.plist
else
    updateScriptLog "$clients does not exist...exiting"
    exit 1
fi

elif [[ "$osVers" == 12 ]] ; then updateScriptLog "Executing for macOS 12 or less..." clients="/var/db/locationd/clients.plist" if [[ -f "$clients" ]]; then updateScriptLog "$clients already exists! Moving on..." updateScriptLog "Current key values for $appName app:" updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print :$appIdentifier" $clients)" updateScriptLog "================================="

    # Create a backup of the existing client location services file
    cp $clients /var/db/locationd/clients.BAK

    # Create an extra working backup
    cp $clients /private/var/tmp/

    # Convert our working backup client plist to xml for editing
    plutil -convert xml1 /private/var/tmp/clients.plist

    # Use Plist Buddy to mark-up client plist, enabling app's location services
    /usr/LibExec/PlistBuddy -c "Set :com.$appIdentifier:Authorized true" /private/var/tmp/clients.plist
    # Check return for last command
    if [[ "$?" = "1" ]]; then
        updateScriptLog "Authorized key seems to be missing...re-adding the key"
        /usr/LibExec/PlistBuddy -c "Add :$appIdentifier:Authorized bool true" /private/var/tmp/clients.plist
        updateScriptLog "Adding 'authorized' key for $appName app location services returned: $?"
        #/usr/LibExec/PlistBuddy -c "Set :$appIdentifier:Authorized true" /private/var/tmp/clients.plist
    fi
    updateScriptLog "Setting $appName app location services returned: $?"

    # Convert back to binary
    plutil -convert binary1 /private/var/tmp/clients.plist

    # Put the updated client plist into appropriate dir
    cp /private/var/tmp/clients.plist $clients

    # Kill and restart the location services daemon and remove our temp file
    killall locationd
    rm /private/var/tmp/clients.plist
else
    updateScriptLog "$clients does not exist...exiting"
    exit 1
fi

elif [[ "$osVers" == 14 ]] ; then updateScriptLog "Executing for macOS 14 Sonoma..." clients="/var/db/locationd/clients.plist" if [[ -f "$clients" ]]; then updateScriptLog "$clients already exists! Moving on..."

        # Create a backup of the existing client location services file
        cp $clients /var/db/locationd/clients.BAK

        # Create an extra working backup
        cp $clients /private/var/tmp/

        # Convert our working backup client plist to xml for editing
        plutil -convert xml1 /private/var/tmp/clients.plist

        count=1

        for i in $(/usr/libexec/PlistBuddy -c "Print" /private/var/tmp/clients.plist | grep -a :i$appIdentifier | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}'  | sed "s/..$//");

        do
        updateScriptLog "Current key value for key$count:"
        updateScriptLog "$(/usr/libexec/PlistBuddy -c "Print $i" $clients)"

        # Use Plist Buddy to mark-up client plist, enabling app's location services
        /usr/LibExec/PlistBuddy -c "Set :$i\::Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            updateScriptLog "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :$i\::Authorized bool true" /private/var/tmp/clients.plist
            updateScriptLog "Adding 'authorized' key for $i location services returned: $?"
        fi
        updateScriptLog "Setting $i location services returned: $?"

        ((count=count+1))
        done

        # Convert back to binary
        plutil -convert binary1 /private/var/tmp/clients.plist

        # Put the updated client plist into appropriate dir
        cp /private/var/tmp/clients.plist $clients

        # Kill and restart the location services daemon and remove our temp file
        killall locationd
        #rm /private/var/tmp/clients.plist
    else
        updateScriptLog "$clients does not exist...exiting"
        exit 1
    fi

fi

Display the final return code

exit $? Obviously manually granting permission is another approach but I would agree not acceptable.

Note: Apple have over the years made this and other similar things much harder and sadly will continue to do so. Sonoma made it even more difficult. Pinpoint 1 not written by me used the built-in Apple API which Apple since effectively blocked. I wrote my replacement version to use the Google API originally when the Google API was completely free and had to update it to work with the paid access. I have here now most of the pieces to do it in Sonoma via my python script although enabling Location Services is now the new issue. Who knows what Apple will do next.

— Reply to this email directly, view it on GitHub https://github.com/jelockwood/pinpoint/issues/25#issuecomment-2131339802, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEG7VEUWEJQ636B4WXOKNCDZEC32TAVCNFSM6AAAAABEUK2FVGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMZRGMZTSOBQGI. You are receiving this because you were mentioned.

kevinmcox commented 1 month ago

Munki - Allow Full Disk Access should already include Munki - Allow App Management plus more.

(You shouldn't need to deploy both.)

https://github.com/munki/munki/wiki/PPPC-Privacy-permissions#permission-types