dot_clean -- Merge ._* files with corresponding native files

When you copy certain macOS files to a non-HFS+/APFS formatted disk (such as a file share), the metadata will be extracted from the files and put in invisible files starting with `._`.

This can leads to issues or can look garbage when you send these files to Git.

According to Apple: 

Before Mac OS X, the Mac OS used ‘forked’ files, which have two components: a data fork and a resource fork. The Mac OS Standard (HFS) and Mac OS Extended (HFS Plus) disk formats support forked files. When you move these types of files to other disk formats, the resource fork can be lost.

With Mac OS X, there is a mechanism called “Apple Double” that allows the system to work with disk formats that do not have a forked file feature, such as remote NFS, SMB, WebDAV directories, or local UFS volumes. Apple Double does this by converting the file into two separate files. The first new file keeps the original name and contains the data fork of the original file. The second new file has the name of the original file prefixed by a “._ “ and contains the resource fork of the original file. If you see both files, the ._ file can be safely ignored. Sometimes when deleting a file, the ._ component will not be deleted. If this occurs you can safely delete the ._ file.
— https://web.archive.org/web/20120602061209/http://support.apple.com/kb/TA20578

I'm don't necessarily agree that deleting them is harmless. I've seen cases where doing so would create issues. Last time I remember was while I was an assistant editor for a feature film. I did an rsync and forgot the -E flag. All the asset files lost their metadata and I had to reimport all  manually in Final Cut Pro.

An easy way to fix this is to run the `dot_clean` command, available from the optional Command Line Tools.

dot_clean /Users/fti/Git/SplashBuddy

How to pronounce my name

One of the oldest sound I remember using on my PC was Linus Torvalds' english.au, available on kernel.org. If I remember well, I would do `cat english.au > /dev/dsp` to listen to it.

So I did the same

Now you know how to pronounce my name "François Levaux-Tiffreau" but in short "François Levaux" and my nickname "ftiff" (f-tiff, not "stiff").

François is pronounced "fʁɑ̃swa":

  • fʁ: french
  • ɑ̃: la vie en rose
  • swa: swag

Levaux is pronounced "ləvo":

  • l
  • ə: about
  • v
  • o: no

There you know! It may not be as easy to remember as Puhpine Brieyen, but I'm at the WWDC and I really want to finish this blog post, send my essay for my MSc and enjoy it.

me @ SAN JO

me @ SAN JO

Surfin' USA

Just a small break while packing my stuff for the WWDC. I cannot express how happy I am to finally attend it. I remember when I was 7, asking my father every weekend to drive me to Apple France to visit it. He never did. 

As WWDC is my Christmas, I'm now in the mood of reflecting back on the year that just passed.  

A lot of thing happened: 

  •  Amaris and I launched an Apple Service and Competency Center. We are now partnering within Apple Professional Services and in the process of becoming Jamf Integrator. Our goal is to support internal and external needs for Apple expertise in Europe. More on that soon. 
  • SplashBuddy (formerly CasperSplash) is still not released, as I set the bar too high. The software in itself is pretty simple, but most of the work is to make it solid and easy to use. It's great to see more and more people using it.  
  • We've hired Merieme Paulouin and Christoph Fellner, two amazing MacAdmins. But more will join later this year! 
  • My partner is pregnant with another boy, making the life so much fun and interesting 🙄😂 
  • I spent most of my free time cursing about my MSc in Information Systems Management at the University of Liverpool. and i will continue to do so for the next two years... yippee!

So i hope to take the few days in San Jose to relax and learn. My priorities:

  • meet developers
  • enjoy the bay with my Stand Up Paddle
  • Attend the Keynote
  • Get a free Siri Speaker (offered to all attendees like the iSight camera, of course)

and technically, learn about:

  • UX
  • Localization
  • Cocoa Bindings
  • Best practices  

If you're around, please ping me on Slack or twitter (@ftiff). I'll be around SF/San Jose from June 2 to 10, then around Austin/Houston until 12. 

Making sense of NSOSStatusErrorDomain:-67846

Ever wondered what mean the errors when a Configuration Profile fails to install?

For example: NSOSStatusErrorDomain:-67846

The easiest way is not to go to Jamf Nation, but start with https://osstatus.com/.

With this, we get the following output: errSecRequestLost -- "The request was lost". A good indication that you may have a firewall trying to mess with SSL (something known as Man-in-the-Middle or MitM).

Changing the network solved this issue, and the configuration profile (SCEP Certificate) installed correctly.

KerbMinder will no longer be maintained

We announced on April 1st that KerbMinder and ADPassMon would no longer be maintained.

KerbMinder was a python script created by Peter Bukowinski that would automatically create and renew Kerberos tickets. In 2015, I became a contributor to the project and adapted it so it could run without the computer being bound to AD.

It was a game changer. Not binding to AD became cool and everyone started to talk about it. 

Ben Toms took over ADPassMon from Peter and did some awesome changes. We then created a "secret" channel on Slack to discuss how we could merge the two software together to have it create and renew Kerberos tickets, alert the user when his password was expiring and automatically mount shares (with the help of @kylecrawshaw). 

Then life got in the way. My main client bought Apple Enterprise Connect, and all the others in the team got new jobs. But Joel Rennich joined the channel.

He took over and created NoMAD with the notable help of Owen Pragel. This is what Gala would have been.

Now what's next?

Apple Enterprise Connect and NoMAD are better than KerbMinder and ADPassMon combined. 

We created the following table to assist in choosing between the two. 

In production, I've only used Apple Enterprise Connect. I can assure it's a great software, and support is amazing. I had very good feedback from NoMAD too. 

Thank you all for being part of the journey.

Full-Stack DEP: Modern Mac Deployment

I had the chance to talk at London Apple Admins 28th Meet Up @ Airbnb (July 2016).

We had three presentations:

  • “Being nice with your management tools” – Graham Gilbert, Airbnb
  • “Testing AutoPkg Recipes” – Ben Goodstein, University of Oxford
  • “Full Stack DEP: Modern Mac Deployment” – Francois Levaux-Tiffreau

I loved Graham and Ben's presentations. Graham, who recently joined Airbnb, gave us some insights on how to "Be A Host" with your users. Ben shared his techniques on how to automate AutoPkg recipe testing. The most important part of his story was the background. Like many universities and businesses, Oxford has more than one IT. In fact, they have many, and they don't necessarily work together. How do you roll out a global IT project in this environment? By collaborating. Ben's goal is to allow every IT department at Oxford to create and push AutoPkg recipes.

My presentation was about focusing on the end-user by giving him the proper tools he needs while minimising IT involvement. It was surprisingly close to Graham's presentation while using radically different tools.

Key takeaways:

  • Focus on your users
  • Use Apple Tools 
  • Leverage Apple Professional Services 
  • Consider MicroMDM if using Munki

Thank you to our hosts, Macmule and Graham Gilbert!

 

Solving SMB Performance Issues on macOS

macOS units were experiencing performance issues both authenticating and browsing Hitachi HNAS appliances navigating through any DFS namespace.  This lead to the following issues:

  • Long delays mounting shares, browsing folders, and opening files (15s for auth dialog to appear, 15s to connect). 
  • Slow file searches
  • File corruption
  • Disappearing files
  • Crashing applications
  • Permissions problems
  • Locked files and file naming issues
  • Failed downloads when using Google Chrome to save gmail attachments directly to server
  • Microsoft Office intermittently fails to save documents opened from the server

This was solved by disabling the SMB packet signing.

Read more below!

Read More

AirWatch: Using a EAP-TLS certificate with WPA2 Enterprise (802.11x)

So now you want to get Wi-Fi.

  1. Use a cloud connector and configure Enterprise Integration to request a certificate from your Active Directory CA (ADDS) -- Not covered here
  2. Create a single profile.

In this profile, you'll add two payloads:

  1. Credentials (order is important):
    1. First tab: Upload your CA, and select "Allow access to all applications" and "Allow export from Keychain"
    2. Second tab: use your machine certificate (uncheck everything)
  2. Network:
    1. check Auto-Join
    2. WPA/WPA2 Enteprise. For some reason, if I choose only "WPA2 Enterprise", it fails. But it will then connect as WPA2.
    3. Uncheck "User logs in to authenticate with the network"
    4. Protocols: EAP-TLS
    5. Username: {EnrollmentUser}
    6. Identity Certificate: Certificate #2 (This is why order is important).
    7. Trusted certificates: Check both
    8. Allow trust exceptions: Check

Using AirWatch with Munki

So you want to use AirWatch, but you're unsure about the viability of their Self Service or package management system. I understand. Let me show you how to do it basically. 

You need 3 Devices > File/Actions:

  1. Munki Tools: Download and install latest release. Then upload it to /Library/AW and set Manifest to Install=/Library/AW/munkitools-xx.yy.pkg
  2. Munki Bootstrap: Run=/usr/bin/touch /Users/Shared/.com.googlecode.munki.checkandinstallatstartup
  3. Munki Forcerun: Run=/usr/local/munki/managedsoftwareupdate --auto

I'm aware Forcerun is bad practice and you should reboot before. But I was told by Greg that worst case scenario nothing works until next reboot. I think I'm safe enough.

You need 1 Devices > Products:

  1. Create a product that includes the three File/Actions before.

You need 1 Devices > Profiles:

  1. Custom Settings
<dict>
    <key>PayloadDisplayName</key>
    <string>MacLovin - Munki (Demonstration Setup)</string>
    <key>PayloadEnabled</key>
    <true />
    <key>PayloadIdentifier</key>
    <string>org.maclovin.munki.test</string>
    <key>PayloadUUID</key>
    <string>8214F1A8-0E65-422C-A82C-088502A14FD6</string>
    <key>PayloadType</key>
    <string>ManagedInstalls</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
    <key>SoftwareRepoURL</key>
    <string>http://munki.maclovin.org/munki_repo</string>
    <key>ClientIdentifier</key>
    <string>test_munki_client</string>
</dict>

Now have fun and let me know!

Casper: Forget a package

Forgetting a package is a good way to troubleshoot some behaviours. It doesn't install anything, but the computer will believe the package was never installed.

Installer.app/SWU

​For OS X packages, installed by Installer.app or Software update, simply use sudo pkgutil --forget [package_id]. You can list current installed packages with pkgutil --pkgs

This will get updated at next recon to Inventory > Package Receipts > Installer.app/SWU.

Casper Suite

To change this (unrelated) list, you need to delete the relevant file in /Library/Application Support/JAMF/Receipts, then do a sudo jamf recon

Again, this doesn't do anything but change inventory.

 

iCloud sign-in

 

I can't remember if I already had an option for iCloud sign in. Things I've seen so far:

  • register (a bit annoying) 
  • register using Facebook, then ask for email and password (what??) 
  • register using Facebook, Twitter or google (not sure I like this for privacy) 
  • and new for me: register using iCloud (read below)
image.jpg
image.jpg

At this point, I wonder: it's a free app, why would they allow me to be only a random ID ? 

Getting closer

Getting closer

I knew it! 

I knew it! 

And of course, the nature of this app is to get metrics from all your other account. So random ID ? Not so much. ​

image.jpg

The application in itself is quite nice, with AirPlay feature for a quick dashboard. But it's like.. Very...... V...e....r....y.... Sloooooooooow. Feels like my iPhone 4 when I'm using it on 3G. 

Numerous — Life’s most important numbers available at a glance par Numerous, Inc

https://appsto.re/ch/ycXIV.i

 

 

AirWatch: How to use the REST API

According to the "AirWatch REST API Guide" PDF document that you can get in https://my.air-watch.com, you need:

  • the URL : https://<host>/API/v1/help

  • the Token: aw-tenant-code (or API Key)

  • Authorization: Basic base64.b64encode("username:password")

How to find the Token

  1. Select the right Organization Group

  2. Go to Group & Settings > System > Advanced > API > REST > General

  3. Select "Override"

  4. an API Key will be generated. This is your "aw-tenant-code"

How to Authorize

The easiest way is to use Basic authentication.

  1. Make sure your admin has the correct role. In production, you should create a custom Role, but for test, Console Administrator is fine. Make sure he's in the correct OG, of course.

  2. The form should be "username:password", encoded using Base64. You can do this on OS X terminal (see below)

$ python -c "import base64; print base64.b64encode('login:password')"
bG9naW46cGFzc3dvcmQ=
$

How to test with Curl

$ curl -X "GET" "https://host.awmdm.com/API/v1/help" \
    -H "Authorization: Basic bG9naW46cGFzc3dvcmQ=" \
    -H "aw-tenant-code: bG9naW46cGFzc3dvcmFzZG/2FmYXNkZmFkc2Zhc2Zk="

With Python

# Install the Python Requests library:
# `pip install requests`

import requests


def send_request():
    # My API
    # GET https://host.awmdm.com/API/v1/help

    try:
        response = requests.get(
            url="https://host.awmdm.com/API/v1/help",
            headers={
                "Authorization": "Basic bG9naW46cGFzc3dvcmQ=",
                "aw-tenant-code": "bG9naW46cGFzc3dvcmFzZGZ/2FmYXNkZmFkc2Zhc2Zk=",
            },
        )
        print('Response HTTP Status Code: {status_code}'.format(
            status_code=response.status_code))
        print('Response HTTP Response Body: {content}'.format(
            content=response.content))
    except requests.exceptions.RequestException:
        print('HTTP Request failed')

Or just use Paw https://luckymarmot.com/paw ;-)

One More Thing…

It doesn't work with OS X clients:

<AirWatchFaultContract xmlns="http://www.air-watch.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <ActivityId>56b6ed75-30a2-418e-84fa-f8e04d35506a</ActivityId>
  <ErrorCode>501</ErrorCode>
  <Message>Functionality not supported for device type : AppleOsX</Message>
</AirWatchFaultContract>

AirWatch: Deploy custom MCX profiles

In order to deploy custom MCX profiles, I will use the excellent mcxToProfile tool by Tim Sutton. Get it here -> https://github.com/timsutton/mcxToProfile

My goal here is to change the delay to ask password to "Immediately". 

0. Install mcxToProfile. I use git as I find it easier to update, but you can also download it directory from the github page. You might need to make the python script executable (see below)

$ git clone https://github.com/timsutton/mcxToProfile.git
$ chmod +x ./mcxToProfile/mcxToProfile.py
  1. Make the changes to your Mac (Here, I go to System Preferences > Security & Confidentiality > General and I change the setting to "Immediately".
  2. Now, find the defaults domain. This is almost an art, I won't cover this here. In this case, it is com.apple.screensaver
  3. Launch mcxToProfile to create the .mobileconfig
$ ./mcxToProfile/mcxToProfile.py --defaults com.apple.screensaver --identifier org.maclovin.screensaver
$ cat org.maclovin.screensaver.mobileconfig
<?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>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadContent</key>
            <dict>
                <key>com.apple.screensaver</key>
                <dict>
                    <key>Forced</key>
                    <array>
                        <dict>
                            <key>mcx_preference_settings</key>
                            <dict>
                                <key>askForPassword</key>
                                <integer>1</integer>
                                <key>askForPasswordDelay</key>
                                <real>60</real>
                                <key>tokenRemovalAction</key>
                                <integer>0</integer>
                            </dict>
                        </dict>
                    </array>
                </dict>
            </dict>
            <key>PayloadEnabled</key>
            <true/>
            <key>PayloadIdentifier</key>
            <string>MCXToProfile.f4859170-42b5-467f-a249-220c689103ec.alacarte.customsettings.3fad436d-d335-4d08-849e-3feda8397631</string>
            <key>PayloadType</key>
            <string>com.apple.ManagedClient.preferences</string>
            <key>PayloadUUID</key>
            <string>3fad436d-d335-4d08-849e-3feda8397631</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
        </dict>
    </array>
    <key>PayloadDescription</key>
    <string>Included custom settings:
com.apple.screensaver

Git revision: a14a19d7f0</string>
    <key>PayloadDisplayName</key>
    <string>MCXToProfile: com.apple.screensaver</string>
    <key>PayloadIdentifier</key>
    <string>org.maclovin.screensaver</string>
    <key>PayloadOrganization</key>
    <string></string>
    <key>PayloadRemovalDisallowed</key>
    <true/>
    <key>PayloadScope</key>
    <string>System</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>f4859170-42b5-467f-a249-220c689103ec</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

You can double click on this file to install it manually (or use $ open org.maclovin.screensaver.mobileconfig). Restart System Preferences to see this setting in the GUI (Security & Confidentiality > General). Then remove this profile, we'll move on to AirWatch.

Now you need to import this to AirWatch:

  1. Go to console
  2. Go to Devices > Profiles > List view
  3. Add > Add Profile
  4. Apple Mac OS X > Device Profile
  5. Fill General infos 

Go to Custom settings and paste only the relevant portion:

        <dict>
            <key>PayloadContent</key>
            <dict>
                <key>com.apple.screensaver</key>
                <dict>
                    <key>Forced</key>
                    <array>
                        <dict>
                            <key>mcx_preference_settings</key>
                            <dict>
                                <key>askForPassword</key>
                                <integer>1</integer>
                                <key>askForPasswordDelay</key>
                                <real>60</real>
                                <key>tokenRemovalAction</key>
                                <integer>0</integer>
                            </dict>
                        </dict>
                    </array>
                </dict>
            </dict>
            <key>PayloadEnabled</key>
            <true/>
            <key>PayloadIdentifier</key>
            <string>MCXToProfile.f4859170-42b5-467f-a249-220c689103ec.alacarte.customsettings.3fad436d-d335-4d08-849e-3feda8397631</string>
            <key>PayloadType</key>
            <string>com.apple.ManagedClient.preferences</string>
            <key>PayloadUUID</key>
            <string>3fad436d-d335-4d08-849e-3feda8397631</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
        </dict>

Now it should be working fine

Office 2016: Where is the name of the user stored ?

If you deployed Office 2016 with a volume license, chances are your user will complain that the name used for reviews (or Auto-Track changes) is "Microsoft Office User" with initials "MO" (or any localized variation).

It is stored here : ~/Library/Group Containers/UBF8T346G9.Office/MeContact.plist

minidefrancois:~ fti$ defaults read "/Users/fti/Library/Group Containers/UBF8T346G9.Office/MeContact.plist"
{
    Initials = FTI;
    Name = "Francois Levaux-Tiffreau";
}

I started an idea, but don't have the time to figure out the Initials:

minidefrancois:~ fti$ defaults write "/Users/fti/Library/Group Containers/UBF8T346G9.Office/MeContact.plist" Name "`finger $USER | awk -F: '{ print $3 }' | head -n1 | sed 's/^ //'`"
minidefrancois:~ fti$ defaults read "/Users/fti/Library/Group Containers/UBF8T346G9.Office/MeContact.plist"
{
    Initials = MO;
    Name = "Francois Levaux-Tiffreau";
}