Archive
profiles command includes client-side rate limitation for certain functions on macOS 12.3
One of the changes brought with macOS 12.3 is that the profiles command line tool now includes a rate limiter for some of its functions:
profiles show
profiles validate
In both cases, running these functions may be limited to once every 23 hours.
For those familiar with rate limitation on the server side, where a server may choose to limit how many calls can be received in a set period from a client, this rate limitation is similar but is set and managed entirely on the client side. This means that there is no bypassing the profiles command’s rate limitation in this case for the Mac in question.
One way this may appear is on Macs which are part of the Automated Device Enrollment program, where the Mac can show its enrollment status by running the following command:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
profiles show -type enrollment |
In the event that this command errors, the profiles command will block further attempts to display this information for the next 23 hours. In this situation, you may see output like that shown below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
username@computername ~ % sudo profiles show -type enrollment | |
Password: | |
Device Enrollment configuration: | |
(null) | |
username@computername ~ % sudo profiles show -type enrollment | |
Error fetching Device Enrollment configuration – Request too soon. Try again later. |
At this time, I don’t know where the information which tracks this 23 hour limitation is stored, but I did confirm that it is stored somewhere in the writable portion of the Mac’s boot drive. Wiping the Mac’s boot drive, via a disk wipe and OS reinstall or via Erase All Contents and Settings, will remove whatever is tracking and enforcing the 23 hour limitation.
Update – 4-22-2022:
It looks like the file which tracks this information is stored in the following location:
/private/var/db/ConfigurationProfiles/Settings/.profilesFetchTimerCheck
This file is protected by SIP. Thanks to zolotkey in the comments!
Also, in the original version of this post, I had made a mistake and conflated the functions of the following commands:
- profiles renew -type enrollment
- profiles show -type enrollment
The profiles renew -type enrollment command can be used to enroll or re-enroll a Mac which is part of the Automated Device Enrollment program with the MDM server that ADE associates the Mac with. To the best of my knowledge, the renew function of the profiles command does not have a client side rate limitation on macOS 12.3. Thanks also to Richard in the comments for catching my mistake and letting me know about it.
Using macOS installer disk images to boot VMware Fusion virtual machines to macOS Recovery
Booting a VMware Fusion virtual machine to the macOS Recovery environment can be challenging, as Fusion uses Command-R as a keyboard shortcut for restoring snapshots.
This is the same keyboard shortcut as booting to macOS Recovery for Intel Macs so if you’re not very fast, or you don’t have the virtual machine window selected correctly, you may be looking at an unwanted request to restore a snapshot instead of macOS Recovery.
Fortunately, there’s a workaround for this behavior which will reliably get you into macOS Recovery. For more details, please see below the jump.
Using custom variables in an AutoPkg recipe to set version information
As part of a recent task to build an AutoPkg recipe which creates an installer package for a screen saver, I ran into an issue. The vendor, for reasons that no doubt make sense to them, split the version information for the screen saver across two separate keys:
- Major part of the version number: Stored in the CFBundleShortVersionString key of the screen saver’s Info.plist file
- Minor part of the version number: Stored in the CFBundleVersion key of the screen saver’s Info.plist file
What this meant is that for version 1.4 of the screen saver, the version information was stored as follows:
- CFBundleShortVersionString key: 1
- CFBundleVersion key: 4
Getting this information was not the problem. AutoPkg includes a PlistReader processor which allows multiple values to be read from one plist file, so I used it as shown below to read the CFBundleShortVersionString key’s and the CFBundleVersion key’s values and store them in the following variables:
- CFBundleVersion key: minor_version
- CFBundleShortVersionString: major_version
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dict> | |
<key>Arguments</key> | |
<dict> | |
<key>info_path</key> | |
<string>%pathname%/Carousel Cloud.saver/Contents/Info.plist</string> | |
<key>plist_keys</key> | |
<dict> | |
<key>CFBundleVersion</key> | |
<string>minor_version</string> | |
<key>CFBundleShortVersionString</key> | |
<string>major_version</string> | |
</dict> | |
</dict> | |
<key>Processor</key> | |
<string>PlistReader</string> | |
</dict> |
So now I had the version info (in separate pieces) and now I needed to put them together. The problem I was seeing was that my usual solution, AutoPkg’s Versioner processor is set up to read one value from a plist file. I had two values and neither were in a plist file.
Fortunately, there are multiple ways to solve this problem. The first I thought of was to build a new plist as part of the recipe’s run and put the version information in. The workflow works like this:
1. Use the PlistReader processor to read the desired information.
2. Use the FileCreator processor processor to create a new plist file with the version information formatted as needed.
3. Use the PlistReader processor to read the version information out of the newly-created plist file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dict> | |
<key>Arguments</key> | |
<dict> | |
<key>info_path</key> | |
<string>%pathname%/Carousel Cloud.saver/Contents/Info.plist</string> | |
<key>plist_keys</key> | |
<dict> | |
<key>CFBundleVersion</key> | |
<string>minor_version</string> | |
<key>CFBundleShortVersionString</key> | |
<string>major_version</string> | |
</dict> | |
</dict> | |
<key>Processor</key> | |
<string>PlistReader</string> | |
</dict> | |
<dict> | |
<key>Processor</key> | |
<string>FileCreator</string> | |
<key>Arguments</key> | |
<dict> | |
<key>file_path</key> | |
<string>%RECIPE_CACHE_DIR%/com.companyname.carouselcloudscreensaver.plist</string> | |
<key>file_mode</key> | |
<string>0755</string> | |
<key>file_content</key> | |
<string><?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>complete_version</key> | |
<string>%major_version%.%minor_version%</string> | |
</dict> | |
</plist> | |
</string> | |
</dict> | |
</dict> | |
<dict> | |
<key>Arguments</key> | |
<dict> | |
<key>info_path</key> | |
<string>%RECIPE_CACHE_DIR%/com.companyname.carouselcloudscreensaver.plist</string> | |
<key>plist_keys</key> | |
<dict> | |
<key>complete_version</key> | |
<string>version</string> | |
</dict> | |
</dict> | |
<key>Processor</key> | |
<string>PlistReader</string> | |
</dict> |
This approach works, but now you have a plist file to clean up later. Another approach is to use custom variable assigning as part of another AutoPkg processor’s run. In this case, you’re using an AutoPkg processor and adding a separate argument which is probably unrelated to the other work the processor is doing, but does the value assignment work you couldn’t accomplish otherwise.
A pretty safe processor to use for this is the EndOfCheckPhase processor. The reason is that by itself, the EndOfCheckPhase processor takes no actions. Instead, it’s used as a marker in AutoPkg recipes to tell AutoPkg to stop checking for new information as part of a recipe’s run. However, even though the EndOfCheckPhase processor doesn’t take actions and doesn’t by default include Arguments values, AutoPkg will still process Arguments values if they’re defined for the EndOfCheckPhase processor. That allows custom variables to be set with values that you couldn’t otherwise set and pass them to AutoPkg. The workflow in this case looks like this:
1. Add the EndOfCheckPhase processor to the very end of the recipe.
2. Perform the desired variable assignment as an Arguments value
The reason to add it to the end is to make sure that all of the other tasks the recipe is performing are completed by the time this processor runs.
In this case, I used this method with the the EndOfCheckPhase processor in the screen saver’s .download recipe to assign the version variable to use the values of the major_version and minor_version variables, separated by a period.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dict> | |
<key>Processor</key> | |
<string>EndOfCheckPhase</string> | |
<key>Arguments</key> | |
<dict> | |
<key>version</key> | |
<string>%major_version%.%minor_version%</string> | |
</dict> | |
</dict> |
The result for the latest version of the screen saver software is that the version variable is assigned the following value:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'version': '1.4' |
I’ve posted the recipes which use this technique for setting version information to GitHub. They’re available via the link below:
https://github.com/autopkg/rtrouton-recipes/tree/master/CarouselCloudScreenSaver
Jamf Pro Server software no longer supported on macOS as of Jamf Pro 10.37.0
To follow up on my earlier posts on the Jamf Pro Server Installer for macOS being retired, Jamf has added the following to the Deprecations and Removals section of the Jamf Pro 10.36.0 release notes:
Support Ending for Hosting Jamf Pro Server on macOS—Starting with the release of Jamf Pro 10.37.0, hosting the Jamf Pro server on macOS will no longer be supported. Mac computers with Apple silicon are not supported by the Jamf Pro Installer for macOS. In addition, the Jamf Pro Installer for macOS will not be available to download. The Jamf Pro utilities that were included in the Jamf Pro Installer for macOS—Composer, Jamf Admin, Jamf Recon, and Jamf Remote—will be made available as a separate download.
If you want to migrate your Jamf Pro server from macOS to Jamf Cloud, contact Jamf Support. If you want to keep your server on premise, you can migrate your Jamf Pro server to one of the following servers: Red Hat Enterprise Linux, Ubuntu, or Windows. For more information, see the Migrating to Another Server article.
For those folks who are running on-premise Jamf Pro servers on Macs, I strongly recommend contacting Jamf Support right now and plan a migration if you haven’t already. As of February 21st, 2022, Jamf’s published support for running Jamf Pro includes the following OS, database and Java versions:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Recommended Configuration: | |
Operating Systems: | |
Windows Server 2019 | |
Ubuntu Server 20.04 LTS | |
Red Hat Enterprise Linux 7.x | |
Database software versions: | |
MySQL 8.0.27 – InnoDB | |
Amazon Aurora (MySQL 5.7 compatible) | |
MySQL 5.7.36 or later – InnoDB | |
Java version: | |
OpenJDK 11 | |
Minimum Supported: | |
Operating Systems: | |
Windows Server 2016 | |
Windows Server 2012 R2 | |
Ubuntu Server 18.04 LTS | |
macOS 10.15 (Support for the Jamf Pro Installer for macOS and hosting Jamf Pro server on macOS will be discontinued with the release of Jamf Pro 10.37.0.) | |
macOS 10.14 (Support for the Jamf Pro Installer for macOS and hosting Jamf Pro server on macOS will be discontinued with the release of Jamf Pro 10.37.0.) | |
Database software versions: | |
MySQL 5.7.36 – InnoDB | |
MySQL 5.7.8 on Amazon RDS – InnoDB | |
Java version: | |
Oracle Java 11 |
autopkg-conductor updated to support both JamfUploaderSlacker and Slacker AutoPkg processors
As part of my preparations for Jamf’s planned authentication changes to the Classic API, I’ve been working more with the JamfUploader AutoPkg processors for Jamf Upload. These processors have emerged as a successor to JSSImporter, the original tool available to upload installer packages and other components to Jamf Pro using AutoPkg.
As part of my work with Jamf Upload, I’ve also updated my autopkg-conductor script to allow the use of either Jamf Upload’s JamfUploaderSlacker AutoPkg processor or JSSImporter’s Slacker AutoPkg processors. For more details, please see below the jump.
Querying an API for AutoPkg download URLs
As part of working on a new AutoPkg download recipe today, I very quickly got stuck on a problem. The app in question is Poly’s Lens software and its download page uses JavaScript to provide the download URL for the latest version of the Lens software. While this may have benefits for the vendor, this means I can’t scrape the page for the download URL’s address using AutoPkg.
Discussing the issue in the #autopkg channel of the MacAdmins Slack, folks started poking around the Lens app and discovered that it was using the Squirrel framework to provide software update functionality to the app. Assuming that meant that the app would phone home for updates, ahousseini was kind enough to monitor the app’s HTTP and HTTPS traffic using CharlesProxy. Shortly thereafter, he reported seeing Lens send the following API request using curl:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
curl \ | |
-H 'Host: api.silica-prod01.io.lens.poly.com' \ | |
-H 'accept: application/json, text/javascript, */*; q=0.01' \ | |
-H 'content-type: application/json' \ | |
-H 'origin: https://www.poly.com' \ | |
-H 'apollographql-client-name: poly.com-website' \ | |
-H 'accept-language: en-GB,en;q=0.9' \ | |
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15' \ | |
-H 'referer: https://www.poly.com/' –data-binary '{"query":"\n query {\n availableProductSoftwareByPid(pid:\"lens-desktop-mac\") {\n name\n version\n publishDate\n productBuild {\n archiveUrl\n }\n }\n }"}' \ | |
–compressed 'https://api.silica-prod01.io.lens.poly.com/graphql' |
This HTTPS traffic was Lens sending an API request to see if it was running the latest version of the software. The relevant parts from our perspective were the items shown below:
This told us what format we should expect API output to be (in this case, JSON):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-H 'content-type: application/json' |
This told us the query which was being sent to the API endpoint:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
–data-binary '{"query":"\n query {\n availableProductSoftwareByPid(pid:\"lens-desktop-mac\") {\n name\n version\n publishDate\n productBuild {\n archiveUrl\n }\n }\n }"}' |
This told us the API endpoint:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://api.silica-prod01.io.lens.poly.com/graphql |
Putting this information together, the following curl command gets a response from the API endpoint:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
curl 'https://api.silica-prod01.io.lens.poly.com/graphql' -H 'content-type: application/json' –data-binary '{"query":"\n query {\n availableProductSoftwareByPid(pid:\"lens-desktop-mac\") {\n name\n version\n publishDate\n productBuild {\n archiveUrl\n }\n }\n }"}' |
The API response looks similar to this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"data":{"availableProductSoftwareByPid":{"name":"Poly Lens Mac – 1.1.11","version":"1.1.11","publishDate":"2022-02-02T17:01:41.503Z","productBuild":{"archiveUrl":"https://swupdate.lens.poly.com/lens-desktop-mac/1.1.11/1.1.11/PolyLens-1.1.11.dmg"}}}} |
Part of the API response’s output includes the download URL for the latest version:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://swupdate.lens.poly.com/lens-desktop-mac/1.1.11/1.1.11/PolyLens-1.1.11.dmg |
Now that we have this information, how to use it with AutoPkg? For more details, please see below the jump:
Zsh history command doesn’t show all history entries by default
Starting with macOS Catalina, Apple’s default shell for the Terminal changed from bash to zsh. As part of that change, the behavior of the history command changed.
Bash:
Running the history command lists all history entries.
Zsh:
Running the history command lists only the 15 most recent history entries.
To see more history entries, you can pass a numerical value to the history command. However, the bash and zsh shells handle this differently also.
Bash:
history (number_goes_here): Shows the most recent entries as defined by the number.
For example, the command shown below will show the fifteen most recent entries:
history 15
Zsh:
history (number_goes_here): Shows all entries which follow number_goes_here.
For example, the following command will show all history entries after history entry #1 (which will include all history entries):
history 1
history -(number_goes_here): Shows the most recent entries as defined by the number.
For example, the command shown below will show the fifteen most recent entries:
history -15
For those interested in why this behavior is different, I recommend reading the zshbuiltins manpage’s section on the fc command. This can be accessed by running the following command:
man zshbuiltins
The reason is that in the zsh shell, the history command’s mechanism is using the following built-in function:
fc
For my own needs, I wanted to recreate bash‘s default behavior for the history command in the zsh shell. The way I chose to do this was to add the following line to the .zshrc file in my home folder.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
alias history='history 1' |
The .zshrc file is the configuration file for the zsh shell and is used to customize the zsh shell’s behavior. Adding this line to the .zshrc file will run the following command whenever the history command is invoked:
history 1
The downside to this approach is that it interferes with the original functionality of the history command. An alternative approach would be to add the following line to the .zshrc file:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
alias fullhistory='history 1' |
Now all history entries will be displayed when the following command is entered:
fullhistory
Python 2.7 removed from macOS Monterey 12.3 beta
As part of the macOS Monterey 12.3 beta cycle, Apple included the following note in the publicly accessible release notes for the macOS Monterey 12.3 beta release:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Python | |
Deprecations | |
Python 2.7 was removed from macOS in this update. Developers should use Python 3 or an alternative language instead. (39795874) |
https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes
This is a development which Apple has warned about for a while, beginning with macOS Catalina’s release notes:
https://developer.apple.com/documentation/macos-release-notes/macos-catalina-10_15-release-notes
Apple has not included a Python 3 runtime with macOS Monterey, so the removal of Python 2.7 from macOS 12.3 and later will mean that Apple is no longer shipping a Python runtime as part of macOS.
For those who want or need to use an Apple-supplied Python distribution, Python 3 is included as part of Xcode and the Xcode Command Line Tools. Those tools are not part of macOS and will need to be installed separately.
As an alternative, a number of shops have been deploying their own Python 3 distribution. For more information on this, please see Greg Neagle’s Snakes on a Plan session from MacSysAdmin 2020:
Session slides:
http://docs.macsysadmin.se/2020/pdf/SnakesOnAPlan.pdf
Session video:
http://docs.macsysadmin.se/2020/video/Day1Session1.mp4
Jamf Pro server installer for macOS retirement planned for March 2022
To follow up on my earlier post on the Jamf Pro Server Installer for macOS being retired, Jamf has added the following to the Deprecations and Removals section of the Jamf Pro 10.35.0 release notes:
Support ending for the Jamf Pro Server Installer for macOS—Support for using the Jamf Pro Installer for macOS will be discontinued in a future release (estimated removal date: March 2022). Mac computers with Apple silicon are not supported by the Jamf Pro Installer for macOS. If you want to migrate your Jamf Pro server from macOS to Jamf Cloud, contact Jamf Support via Jamf Account. If you want to keep your server on premise, you can migrate your Jamf Pro server from macOS to one of the following servers: Red Hat Enterprise Linux, Ubuntu, or Windows. For more information, see the Migrating to Another Server article.
For those folks who are running on-premise Jamf Pro servers on Macs, I strongly recommend contacting Jamf Support and plan a migration if you haven’t already. As of January 14th, 2022, Jamf’s published support for running Jamf Pro includes the following OS, database and Java versions:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Recommended Configuration: | |
Operating Systems: | |
Windows Server 2019 | |
Ubuntu Server 20.04 LTS | |
Red Hat Enterprise Linux 7.x | |
Database software versions: | |
MySQL 8.0 – InnoDB | |
Amazon Aurora (MySQL 5.7 compatible) | |
MySQL 5.7.13 or later – InnoDB | |
Java version: | |
OpenJDK 11 | |
Minimum Supported: | |
Operating Systems: | |
Windows Server 2016 | |
Windows Server 2012 R2 | |
Ubuntu Server 18.04 LTS | |
macOS 10.15 | |
macOS 10.14 | |
Database software versions: | |
MySQL 5.7.13 – InnoDB | |
MySQL 5.7.13 on Amazon RDS – InnoDB | |
Java version: | |
Oracle Java 11 |
Preventing user and location inventory information from being changed by the jamf binary’s recon verb
You can allow or prevent local administrators on the computer from changing User and Location inventory information in Jamf Pro with the jamf binary by using the Allow local administrators to use the jamf binary recon verb to change User and Location inventory information in Jamf Pro checkbox. This is a feature which first appeared in Jamf Pro 10.20.x, but may not be well known.
This setting is enabled by default and can be configured by navigating to Settings > Computer Management > Inventory Collection in Jamf Pro.
What this setting affects are the following options associated with the jamf binary’s recon verb:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-endUsername | |
-realname | |
-position | |
-building | |
-department | |
-phone | |
-room |
Why disable this setting? If you have workflows which leverage the user and location information stored in Jamf Pro, being able to change this setting from a managed Mac using the jamf binary’s recon verb may have security implications. In particular, PKI certificate authorities set up in Jamf Pro may use the user and location information stored in Jamf Pro to issue certificates to managed Macs.
In the context of certificates used for authentication, being able to change the user and location stored in Jamf Pro from the managed Mac’s end may mean that an enduser with the ability to run the jamf binary’s recon verb may be able to get authentication certificates for someone other than themselves assigned to their Mac.
If you do not have any workflows that use the recon verb’s options specified above, my advice is that you disable this setting and remove the ability of managed Macs to change the user and location information stored in Jamf Pro using the jamf binary’s recon verb.
Recent Comments