Location Services

whiteb
Contributor II

Is it still the case that there is no way of allowing Location Services for a specific app, for non admin users? I don’t see a PPPC option for it, and it’s been stated that this is impossible in the past.

Zoom soft-phone client wants location services enabled for 911 call routing. Users don’t have admin rights.

I've seen someone say the below works for Big Sur, but even then I believe that just enables the general Apple location services, and not specifically for an app in particular.

#!/bin/sh

sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -int 1

sudo /usr/bin/defaults write /Library/Preferences/com.apple.timezone.auto Active -bool true

I need Location Services checked for Zoom specifically.

1 ACCEPTED SOLUTION

whiteb
Contributor II

I ended up putting in a Jamf support ticket on this. Went back and forth a little, it got escalated. In the end, their final answer was that it's an intentional limitation on Apple's end that MDM's do not have the ability to do this. Pretty sure their reasoning is privacy. Which I get, but still..

I believe our network admin who is mainly doing the Zoom phone transition/integration said you can configure Zoom Phone admin settings to associate different subnets with different building locations. So if they're calling 911 with Zoom Phone on a Mac, it will look at their subnet and pull 911 location that way. This was the best we were able to do.

View solution in original post

10 REPLIES 10

Scott_Conway
New Contributor III

Also in this situation for MS Teams. Would like to know if there is a solution for this.

jason_smith3
New Contributor

Same situation here for Zoom. Any insight into how to make this work yet?

whiteb
Contributor II

I ended up putting in a Jamf support ticket on this. Went back and forth a little, it got escalated. In the end, their final answer was that it's an intentional limitation on Apple's end that MDM's do not have the ability to do this. Pretty sure their reasoning is privacy. Which I get, but still..

I believe our network admin who is mainly doing the Zoom phone transition/integration said you can configure Zoom Phone admin settings to associate different subnets with different building locations. So if they're calling 911 with Zoom Phone on a Mac, it will look at their subnet and pull 911 location that way. This was the best we were able to do.

Scott_Conway
New Contributor III

Our MS Teams admin does the same thing. However this doesn't help the home office users, which relies on location services. The only thing I can think of is instructing the users to enable this on their own.

Makes sense. We've pulled admin rights so unfortunately not an option for us :\

williamaddis
New Contributor II

We actually got the same responses from Jamf/Apple when asking for better ways to do this other than "give the users admin rights and have them enable the app location manually". We had the need to enable location services for Teams (and Teams Helper) for our E911 calling. Not satisfied with those responses I dug deeper and found a way to 100% automate enabling app location services. This script is for Teams and Teams Helper, but you can review the queried file and substitute in whatever app you need (Chrome, Zoom, etc). macOS Ventura adds a GUID to the file entries so there are pre-macOS 13 and post-macOS 13 sections of the script.

First, we check if location services is enabled, if yes we continue, if not we call a different script to enable it (you will have to replace that jamf policy statement on Line 33 with the commands to enable location services listed at the beginning of this whole thread).

#!/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
####################################################################################################

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

# Echo mount point in Jamf
echo $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
	echo ""
	echo "Location Services are enabled, moving on..."
    echo ""
else
	echo ""
	echo "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
    	echo "Unable to enable location services...exiting"
        exit 1
    fi
fi

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

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

if [[ "$osVers" == *13* ]] ; then
echo "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 :com.microsoft.teams | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}' | head -1)
        key2=$(/usr/libexec/PlistBuddy -c "Print" /var/db/locationd/clients.plist | grep :com.microsoft.teams | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}' | tail -1)
        echo "$clients already exists! Moving on..."
        echo ""
        echo "Current key values for teams app and teams helper:"
        echo $(/usr/libexec/PlistBuddy -c "Print $key1" $clients)
        echo ""
        echo $(/usr/libexec/PlistBuddy -c "Print $key2" $clients)
        echo ""
        echo "================================="

        # 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 Teams' location services
        /usr/LibExec/PlistBuddy -c "Set :$key1:Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            echo "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :$key1:Authorized bool true" /private/var/tmp/clients.plist
            echo "Adding 'authorized' key for Teams app location services returned: $?"
            #/usr/LibExec/PlistBuddy -c "Set :$key1:Authorized true" /private/var/tmp/clients.plist
        fi
        echo "Setting Teams app location services returned: $?"

        /usr/LibExec/PlistBuddy -c "Set :$key2:Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            echo "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :$key2:Authorized bool true" /private/var/tmp/clients.plist
            echo "Adding 'authorized' key for Teams helper location services returned: $?"
            #/usr/LibExec/PlistBuddy -c "Set :$key2:Authorized true" /private/var/tmp/clients.plist
        fi
        echo "Enabling Teams helper 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
        echo "$clients does not exist...exiting"
        exit 1
    fi
  else
    echo "Executing for macOS 12 or less..."
    clients="/var/db/locationd/clients.plist"
    if [[ -f "$clients" ]]; then
        echo "$clients already exists! Moving on..."
        echo ""
        echo "Current key values for teams app and teams helper:"
        echo $(/usr/libexec/PlistBuddy -c "Print :com.microsoft.teams" $clients)
        echo ""
        echo $(/usr/libexec/PlistBuddy -c "Print :com.microsoft.teams.helper" $clients)
        echo ""
        echo "================================="

        # 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 Teams' location services
        /usr/LibExec/PlistBuddy -c "Set :com.microsoft.teams:Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            echo "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :com.microsoft.teams:Authorized bool true" /private/var/tmp/clients.plist
            echo "Adding 'authorized' key for Teams app location services returned: $?"
            #/usr/LibExec/PlistBuddy -c "Set :com.microsoft.teams:Authorized true" /private/var/tmp/clients.plist
        fi
        echo "Setting Teams app location services returned: $?"

        /usr/LibExec/PlistBuddy -c "Set :com.microsoft.teams.helper:Authorized true" /private/var/tmp/clients.plist
        # Check return for last command
        if [[ "$?" = "1" ]]; then
            echo "Authorized key seems to be missing...re-adding the key"
            /usr/LibExec/PlistBuddy -c "Add :com.microsoft.teams.helper:Authorized bool true" /private/var/tmp/clients.plist
            echo "Adding 'authorized' key for Teams helper location services returned: $?"
            #/usr/LibExec/PlistBuddy -c "Set :com.microsoft.teams.helper:Authorized true" /private/var/tmp/clients.plist
        fi
        echo "Enabling Teams helper 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
        echo "$clients does not exist...exiting"
        exit 1
    fi
fi
# Display the final return code 
exit $?

 From there, we created an extension attribute to read/report on whether or not Teams location services are enabled and just have this policy set to run this script Ongoing/Recurring Check-in/All Managed Clients (exclude smart group of machines with Teams location enabled created via the ext. attribute). 

Extension attribute (we named it Teams Location Services Enabled):

#!/bin/bash

osVers=$(sw_vers -productVersion)

if [[ "$osVers" == *13* ]] ; then
    key1=$(/usr/libexec/PlistBuddy -c "Print" /var/db/locationd/clients.plist | grep :com.microsoft.teams | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}' | head -1)
    key2=$(/usr/libexec/PlistBuddy -c "Print" /var/db/locationd/clients.plist | grep :com.microsoft.teams | awk -F '=Dict{' '{gsub(/ /,"");gsub(":","\\:");print $1}' | tail -1)

    teamsapp_location=$(/usr/LibExec/PlistBuddy -c "Print :$key1:Authorized" /var/db/locationd/clients.plist)
    teamshelper_location=$(/usr/LibExec/PlistBuddy -c "Print :$key2:Authorized" /var/db/locationd/clients.plist)

else
    teamsapp_location=$(/usr/libexec/PlistBuddy -c "Print :com.microsoft.teams:Authorized" /var/db/locationd/clients.plist)
    teamshelper_location=$(/usr/libexec/PlistBuddy -c "Print :com.microsoft.teams.helper:Authorized" /var/db/locationd/clients.plist)
fi

if [[ $teamshelper_location == "true" ]] && [[ $teamsapp_location == "true" ]]; then
    echo "<result>true</result>"
else
    echo "<result>false</result>"
fi

exit 0

 

How are you writing to /var/db/locationd ?

I get operation not permitted no matter the method.

williamaddis
New Contributor II

Are you trying to run the script via a Jamf policy? That should have full rights to do anything. If you are running the sh locally it would need sudo and probably have to give Terminal (or whatever is executing) full disk access in PPPC settings.  Maybe attach a log of what you're getting and it will help. Thanks.

Thank you much! I was testing out of my terminal and completely forgot about it not having Disk Access enabled for it. I rewrote the JAMF policy execution from,

jamf policy -event location

to

sudo -u "_locationd" defaults -currentHost write "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled -int 1

It appears to be working well for what we need thank you for sharing your solution.

williamaddis
New Contributor II

Great, I'm glad it was helpful to you!  The location entries do not show up until the app has been opened for the first time, so we have our policy set to run Ongoing at recurring check-in for all machines (excluding machines that already have it enabled; via the extension attribute inventory).  Running this just once during a build/provision probably won't work correctly since the apps will not have been opened.