krypted.com

Tiny Deathstars of Foulness

Clients discover the Apple Caching service bundled with macOS Server (and in the future macOS) automatically. You can create a text recored for _aaplcache._tcp on your DNS server. That would look

_aaplcache._tcp 518400 IN TXT “prs=192.168.50.100”

Name: _aaplcache._tcp with a type of TXT and a TTL of 518400 seconds. The prs is the address to be used and is set to a value using prs=192.168.50.100.

June 15th, 2017

Posted In: Mac OS X Server

Tags: , , , ,

Leave a Comment

I mentioned mdmclient when I gave the talk on the inner workings of Mobile Device Management, or MDM. There, I spent a lot of time on APNs and profiles, but just kinda’ spoke about mdmclient in terms of it being the agent that runs on macOS to provide mdm parity for the Mac. The mdmclient binary is located at /usr/libexec/mdmclient and provides pretty limited access to see how the Mac reacts to and interprets information coming from a device management provider.

I had been meaning to do a write-up on mdmclient and document what it can do since it first shipped. But as luck would have it, @Mosen on the Slacks beat me to the punch with a fantastic resource at https://mosen.github.io/profiledocs/troubleshooting/mdmclient.html. So here I’d like to focus on just 3 examples of using mdmclient. The first is to see what insight an MDM has to the applications installed (whether that information is actually committed to a database somewhere or not) using QueryInstalledApps:

/usr/libexec/mdmclient QueryInstalledApps

Here, we can see an array output of each bundle installed:

{BundleSize = 27457223;
Identifier = “com.hipchat.HipChat”;
Name = HipChat;
ShortVersion = “3.1.6”;
Version = “3.1.6”;}

Now, we can end up with duplicates, and so focus on just the unique Identifier keys, as follows:

/usr/libexec/mdmclient QueryInstalledApps | grep Identifier | uniq

The second iteration is to see installed profiles. The most basic of these, is to see user profiles, which can be obtained using QueryInstalledProfiles, as follows:

/usr/libexec/mdmclient QueryInstalledProfiles

Now, I could see using the profiles command with the -L option that I have a profile to configure office365 on my machine:

profiles -L

charlesedge[1] attribute: profileIdentifier: com.jamfsw.office365.a5f0e328-ea86-11e3-a26c-6476bab5f328
There are 1 user configuration profiles installed for ‘charlesedge’

So to see what that same information looks like, when queried from an MDM solution:
/usr/libexec/mdmclient QueryInstalledProfiles

QueryInstalledProfiles then returns:

({HasRemovalPasscode = 0;
IsEncrypted = 0;
PayloadContent = (
{PayloadDisplayName = “Charles Edge’s Office 365”;
PayloadIdentifier = “com.jamfsw.office365.a5f0e328-ea86-11e3-a26c-6476bab5f328.exchange.a5f2ccd9-ea86-11e3-b1e0-6476bab5f328”;
PayloadType = “com.apple.ews.account”;
PayloadUUID = “a5f2ccd9-ea86-11e3-b1e0-6476bab5f328”;
PayloadVersion = 1;});
PayloadDescription = “This will configure your Office 365 account for your Mac.”;
PayloadDisplayName = “Charles Edge’s Office 365”;
PayloadIdentifier = “com.jamfsw.office365.a5f0e328-ea86-11e3-a26c-6476bab5f328”;
PayloadOrganization = “JAMF Software”;
PayloadRemovalDisallowed = 0;
PayloadUUID = “a5f0e328-ea86-11e3-a26c-6476bab5f328”;
PayloadVersion = 1;
SignerCertificates = ();})

You can then take action based on this type of information, allow you to either fill a database for agent-based management, or simply take action if something is missing, etc.

QueryInstalledProfiles covers user profiles. To see system, you’ll need installedProfiles:

/usr/libexec/mdmclient installedProfiles | grep "Profile Name"

Run without the grep for a considerably more verbose amount of information.

Finally, let’s look at one more piece of information, which is the hash for the iTunes Store. That’s a point I’ve made a number of times, that the iTunes account email address is never provided to an MDM, once associated to a device or user on a device. Instead, there’s a hash of the account. These are important with VPP, as it allows for reversing (according to the MDM) which users have claimed which apps, or which users are using a given app, as well as how many devices they’re accessing those from. To see a hash, as an MDM sees it:

/usr/libexec/mdmclient QueryAppInstallation | grep iTunesStoreAccountHash

There’s a lot more you can do here, and I’m sure we’ll see a lot more over time. However, the work from @mosen combined with the opening up of the documentation on profiles and the mdm protocol helps to shed some light on how things work under the hood, and how we can use these features to provide greater programatic management for the Mac.

For example, to grab that iTuneshash from earlier, as a Jamf extension attribute you could use the following: https://github.com/krypted/ituneshash/blob/master/ituneshash.sh

April 28th, 2017

Posted In: Mac OS X, Mac OS X Server, Mac Security

Tags: , , , , , , ,

There’s a macOS tool called AssetCacheLocatorUtil located at /usr/bin/AssetCacheLocatorUtil. The output is in… stderr. Because stderr is so fun to work with (note that sed -i only works with stdin). So, to update the caching server(s) you are using and only print the IP address of those, you’d do the following:

/usr/bin/AssetCacheLocatorUtil 2>&1 | grep guid | awk '{print$4}' | sed 's/^\(.*\):.*$/\1/' | uniq

If you use Jamf Pro and would like to use this as an extension attribute, that’s posted here: https://github.com/krypted/cachecheck. I didn’t do any of the if/then there, as I’d usually just do that on the JSS.

April 17th, 2017

Posted In: Mac OS X, Mac Security, Mass Deployment, Network Infrastructure, precache

Tags: , , , , , , , , , ,

I recently had an issue where QuickLook was crashing every time I clicked on certain file types. I thought they were unsupported by QuickLook. But it turns out that they were animated and trying to start while the QuickLook animation was starting. So disable the QuickLook animation and the files appeared as intended. To do so, write a key called QLPanelAnimationDuration into the global defaults database, with a -float value of 0, as follows:

defaults write -g QLPanelAnimationDuration -float 0

April 16th, 2017

Posted In: Mac OS X

Tags: , ,

The xxd is a bash command in Linux and macOS that is used to take a hexdump (convert a string to hex), or convert hex back to a string. To use xxd, just call it with a couple of options. Below, we’ll use the -p option to export into plain hexdump, and we’ll quote it and the <<< is to take input rather than a file name to convert (the default behavior), as follows:

xxd -p <<< "hey it's a string"

The output would be a hex string, as follows:

6865792069742773206120737472696e670a

Then use the -r option to revert your hex back to text. Since xxd doesn’t allow for a positional parameter to revert, we’ll simply echo the hex string and pipe it back into xxd, as follows:

echo 6865792069742773206120737472696e670a | xxd -r -p

And the output would be (is):

hey it's a string

Other useful options:

  • -b: Perform a binary dump instead of a hex dump
  • -e: what it looks like when a little endian takes a hex dump
  • -h: get help with the command
  • -len: stop after the defined number of characters
  • -u: use uppercase in the hex, instead of the default lower-case (doesn’t seem to actually work on macOS)
  • -v: grab the version of xxd

April 2nd, 2017

Posted In: Mac OS X, Mac OS X Server, Mac Security, Ubuntu, Unix

Tags: , , , , , ,

This is the first page of a 5 page piece I just finished writing for MacTech. After the last episode of the MacAdmins podcast though, I wanted to go ahead and get some of the information out there. For a much more detailed analysis, check out MacTech!

Apple has a number of different logging APIs. For the past few releases, Apple has tried to capture everything possible in logs, creating what many administrators and developers might consider to be a lot of chatter. As such, an entirely new interface needed to be developed to categorize and filter messages sent into system logs.

Writing Logs

The logger command is still used to create entries in system logs. However, if you are then using tail to view /var/log/system.log then you will notice that you no longer see your entry being written. This is because as the logs being created in macOS have gotten more complex, the tools to read and write those logs has gotten more complicated as well.

Let’s take a simple log entry. Below, we’ll write the string “Hello Logs” into the system log. To do so, use the –i option to put the process id of the logger process and –s to write to the system log, as well as to stderr. To make the entry easier we’ll tag it with –t followed by the string of the tag. And finally, we’ll quote the entry we want written into the log. This is basically the simplest form of an entry:

logger -is -t krypted "Hello Logs"

Once written, use the log command to read your spiffy new entries. This isn’t terribly different than how things worked previously. If you’re a developer, you will need to note that all of the legacy APIs you might be using, which include asl_log_message, NSLog, and syslog, have been redirected to the new Unified Logging system, provided you build software for 10.12 (you can still build as before for 10.11, iOS 9, tvOS 10, and watchOS 3 and below). These are replaced with the os_log, os_log_info, os_log_debug, os_log_error, os_log_fault, and os_log_create APIs (which correspond to various levels of logs that are written).

Reading Logs

Logs are now stored in the tracev3 formatted files in /var/db/diagnostics, which is a compressed binary format. As with all binary files, you’ll need new tools to read the files. Console has been updated with a new hierarchical capability and the ability to watch activities, subsystems, etc.

The log command provides another means of reading those spiffy new logs. To get started, first check out the man page:

man log

That “Hello Logs” string we used earlier is part of a message that you can easily view using the ‘log show’ command. In the below example, we’ll just run a scan of the last 3 minutes, using the –last option, and then providing a –predicate. We’ll explain those a bit later, but think of it as query parameters – here, we’ll specify to look for “Hello Logs” in eventMessage:

log show --predicate 'eventMessage contains "Hello Logs"' --last 3m

Filtering the log data using “eventMessage CONTAINS “Hello Logs”” shows us that our entry appears as follows:

Timestamp                       Thread     Type        Activity             PID

2017-03-23 23:51:05.236542-0500 0x4b83bb   Default     0x0                  88294  logger: Hello Logs

——————————————————————————————————————–

Log      – Default:          1, Info:                0, Debug:             0, Error:          0, Fault:          0

Activity – Create:           0, Transition:          0, Actions:           0

March 26th, 2017

Posted In: Mac OS X, Mac OS X Server

Tags: , , , , , ,

The next release of iOS (10.3), macOS (10.12.4), and tvOS (10.2) bring us a host of new management features. These include DEP configuration, remote wipe, single app mode, conference room mode, and remote reboot for Apple TVs. The next evolution of iOS brings us sounds in lost mode, the ability to prevent users from connecting to unmanaged wireless networks (just make sure to push that policy after sending down the actual managed wireless networks – or eek), the option to remotely shut down and reboot devices,

The Mac options includes some of the above but also restricting the feature to unlock macOS devices with Touch ID, restrict documents and desktop syncing with Apple’s iCloud service. Shared iPad environments also get new passcode policies.

Jamf Pro 9.98 has also comes with Symantec PKI integration and lots, and lots, and lots of resolutions to product issues. For more, see https://www.jamf.com/blog/are-you-ready-for-apples-next-release/. For a full run-down of profile options and MDM commands: http://docs.jamf.com/9.98/casper-suite/release-notes/What’s_New_in_This_Release.html.

Keeping with Apple’s evolving standards, Managed Preferences and Provisioning Profiles are being deprecated: http://docs.jamf.com/9.98/casper-suite/release-notes/Deprecations_and_Removals.html (which isn’t to say you can’t still deploy these kinds of things using your own scripts, etc).

Finally, if you have a problem in your environment and want to see if it’s been fixed, for a list of defects and product improvements – see http://docs.jamf.com/9.98/casper-suite/release-notes/Bug_Fixes_and_Enhancements.html

March 23rd, 2017

Posted In: JAMF, Mac OS X, Mac OS X Server

Tags: , , , ,

You search for items in macOS using compound conditions in a number of ways. One way is with awk. Here, we’re going to grab the output of a simple ls command. That gets piped into an awk statement. Then we’re going to look at the expression to evaluate. Basically, we’re going to say anything that contains com. as well as apple and .plist. Because it’s ls, we’re looking for names of files that match those patterns. Each pattern is listed in brackets. And then there’s the {print} to lay out the action of printing to the files that match the pattern to the screen:

ls |awk '/[com.][apple][.plist]/ {print}'

Note: I know you’re not supposed to use ls in scripts. Don’t care. If it were dates and such, I’d of used stat…

March 14th, 2017

Posted In: Mac OS X, Mac OS X Server

Tags: , , , ,

If you happen to be tweaking the macOS subsystems for logging, I’ve put them into a little python class. If you need it, find it at this gist:

https://gist.github.com/krypted/495e48a995b2c08d25dc4f67358d1983

Could use an array of all the levels, TTLs, and options. But I’ll get to that when I get some time. If this is all you need, though:

class Logging(object):

__name__ = 'logger.info(1)'
plist = '/System/Library/Preferences/Logging/Subsystems/'

def __init__(__name__, plist, *args, **kwargs):
super(getLogger/, self).__init__()

logger.info('Input parameters:\n'
'accessibility: "{com.apple.Accessibility.plist}"\n'
'StandaloneHIDFudPlugins: "{com.apple.StandaloneHIDFudPlugins.plist}"\n'
'duetactivityscheduler: "{com.apple.duetactivityscheduler.plist}"\n'
'passkit: "{com.apple.passkit.plist}"\n'
'AppKit: "{com.apple.AppKit.plist}"\n'
'SystemConfiguration: "{com.apple.SystemConfiguration.plist}"\n'
'eapol: "{com.apple.eapol.plist}"\n'
'persona: "{com.apple.persona.plist}"\n'
'AppleIR: "{com.apple.AppleIR.plist}"\n'
'TCC: "{com.apple.TCC.plist}"\n'
'icloudpreferences: "{com.apple.icloudpreferences.plist}"\n'
'apple.pf: "{com.apple.pf.plist}"\n'
'AssetCache: "{com.apple.AssetCache.plist}"\n'
'TimeMachine: "{com.apple.TimeMachine.plist}"\n'
'internetAccounts: "{com.apple.internetAccounts.plist}"\n'
'photoanalysisd.graph: "{com.apple.photoanalysisd.graph.plist}"\n'
'AssetCacheServices: "{com.apple.AssetCacheServices.plist}"\n'
'Transport: "{com.apple.Transport.plist}"\n'
'libsqlite3: "{com.apple.libsqlite3.plist}"\n'
'photoanalysisd.job: "{com.apple.photoanalysisd.job.plist}"\n'
'BezelServices: "{com.apple.BezelServices.plist}"\n'
'accounts: "{com.apple.accounts.plist}"\n'
'locationd.Core: "{com.apple.locationd.Core.plist}"\n'
'photoanalysisd: "{com.apple.photoanalysisd.plist}"\n'
'DesktopServices: "{com.apple.DesktopServices.plist}"\n'
'amp.MediaServices: "{com.apple.amp.MediaServices.plist}"\n'
'locationd.Legacy: "{com.apple.locationd.Legacy.plist}"\n'
'pluginkit: "{com.apple.pluginkit.plist}"\n'
'ExchangeWebServices: "{com.apple.ExchangeWebServices.plist}"\n'
'authkit: "{com.apple.authkit.plist}"\n'
'locationd.Motion: "{com.apple.locationd.Motion.plist}"\n'
'sandbox.reporting: "{com.apple.sandbox.reporting.plist}"\n'
'FaceTime: "{com.apple.FaceTime.plist}"\n'
'avfaudio: "{com.apple.avfaudio.plist}"\n'
'locationd.Position: "{com.apple.locationd.Position.plist}"\n'
'sbd: "{com.apple.sbd.plist}"\n'
'Finder: "{com.apple.Finder.plist}"\n'
'awd.awdd: "{com.apple.awd.awdd.plist}"\n'
'locationd.Utility: "{com.apple.locationd.Utility.plist}"\n'
'securityd: "{com.apple.securityd.plist}"\n'
'HTTPServer: "{com.apple.HTTPServer.plist}"\n'
'awd.framework: "{com.apple.awd.framework.plist}"\n'
'mDNSResponder: "{com.apple.mDNSResponder.plist}"\n'
'sharing: "{com.apple.sharing.plist}"\n'
'IDS: "{com.apple.IDS.plist}"\n'
'bluetooth: "{com.apple.bluetooth.plist}"\n'
'mac.install: "{com.apple.mac.install.plist}"\n'
'siri: "{com.apple.siri.plist}"\n'
'IPConfiguration: "{com.apple.IPConfiguration.plist}"\n'
'calendar: "{com.apple.calendar.plist}"\n'
'mail: "{com.apple.mail.plist}"\n'
'social: "{com.apple.social.plist}"\n'
'ManagedClient: "{com.apple.ManagedClient.plist}"\n'
'captive: "{com.apple.captive.plist}"\n'
'mediaremote: "{com.apple.mediaremote.plist}"\n'
'socialpushagent: "{com.apple.socialpushagent.plist}"\n'
'Messages: "{com.apple.Messages.plist}"\n'
'catalyst: "{com.apple.catalyst.plist}"\n'
'multipeerconnectivity: "{com.apple.multipeerconnectivity.plist}"\n'
'symptomsd: "{com.apple.symptomsd.plist}"\n'
'MessagesEvents: "{com.apple.MessagesEvents.plist}"\n'
'cdp: "{com.apple.cdp.plist}"\n'
'network: "{com.apple.network.plist}"\n'
'syncdefaults: "{com.apple.syncdefaults.plist}"\n'
'NetworkSharing: "{com.apple.NetworkSharing.plist}"\n'
'clouddocs: "{com.apple.clouddocs.plist}"\n'
'networkextension: "{com.apple.networkextension.plist}"\n'
'useractivity: "{com.apple.useractivity.plist}"\n'
'ProtectedCloudStorage: "{com.apple.ProtectedCloudStorage.plist}"\n'
'coreanimation: "{com.apple.coreanimation.plist}"\n'
'networkserviceproxy: "{com.apple.networkserviceproxy.plist}"\n'
'Registration: "{com.apple.Registration.plist}"\n'
'coreaudio: "{com.apple.coreaudio.plist}"\n'
'nlcd: "{com.apple.nlcd.plist}"\n'
'SkyLight: "{com.apple.SkyLight.plist}"\n'
'coredata: "{com.apple.coredata.plist}"\n'
'notes: "{com.apple.notes.plist}"\n'

try:
plist()
except Exception as e:
logger.error(e)

March 13th, 2017

Posted In: Mac OS X

Tags: , , , , , , , ,

You can quickly and easily back up your Filewave databases using the fwcontrol command to stop a Filewave server (thus preserving the integrity of the data you are backing up) and then backing up the database using the /fwxserver directory.

To get started, we’ll first down the server. This is done using the fwcontrol command along with the server option and the stop verb, as follows:

sudo fwcontrol server stop

Now that there won’t be data trying to commit into the database, let’s make a backup of the database directory using the cp command:

cp -rp /fwxserver/DB ~/Desktop/Databasebak

To start the database, use the decontrol command with the server option and the start verb, as follows:

fwcontrol server start

Note, if you will be moving to a new Filewave server, you would want to lock clients during this transition, so before restarting your server, use the sqlite3 command to set the status to 1 in the user table:

sqlite3 /fwxserver/DB/server.sqlite 'update user set status = 1;'

February 15th, 2017

Posted In: Mac OS X, Mac OS X Server, Mac Security, Network Infrastructure

Tags: ,

Next Page »