Skip to main content

I have created a simple script that enables sudo to use the TouchID PAM module exactly as conorgriffin explains. It does it in a single script that you can copy-paste to a terminal in it's entirety or use the "curl pipe bash" shortcut:

curl -sL https://gist.githubusercontent.com/RichardBronosky/31660eb4b0f0ba5e673b9bc3c9148a70/raw/touchid_sudo.sh | bash

The complete script:

#!/bin/bash

# curl -sL https://gist.githubusercontent.com/RichardBronosky/31660eb4b0f0ba5e673b9bc3c9148a70/raw/touchid_sudo.sh | bash
# This script is ready to copy-paste in whole, or just the line above (without the leading #)

# Use TouchID for sudo on modern MacBook Pro machines
# This script adds a single line to the top of the PAM configuration for sudo
# See: https://apple.stackexchange.com/q/259093/41827 for more info.

touchid_sudo(){
  sudo bash -eu <<'EOF'
  file=/etc/pam.d/sudo
  # A backup file will be created with the pattern /etc/pam.d/.sudo.1
  # (where 1 is the number of backups, so that rerunning this doesn't make you lose your original)
  bak=$(dirname $file)/.$(basename $file).$(echo $(ls $(dirname $file)/{,.}$(basename $file)* | wc -l))
  cp $file $bak
  awk -v is_done='pam_tid' -v rule='auth       sufficient     pam_tid.so' '
  {
    # $1 is the first field
    # !~ means "does not match pattern"
    if($1 !~ /^#.*/){
      line_number_not_counting_comments++
    }
    # $0 is the whole line
    if(line_number_not_counting_comments==1 && $0 !~ is_done){
      print rule
    }
    print
  }' > $file < $bak
EOF
}

touchid_sudo

This script demonstrates a few cool patterns that I love to teach people who are new to bash or DevOps.

  1. Create a backup file that is numbered rather than simply .bak on the end. (It looks gnarly, but that pattern works with whatever is in $file and is reusable.
  2. To make it safe to do curl ... | bash, wrap everything in a function and call it on the last line. That way if the download is interrupted, nothing is (partially) done.
  3. Put a call to sudo bash -eu in your script so that you don't have tell the user to do it. (-eu are short for errexit and nounset and you should be using them!)
  4. Single quoting bash heredoc 'EOF' to prevent premature shell expansion.
  5. Making inline awk more readable.