Skip to content

Instantly share code, notes, and snippets.

@nadiaholmquist
Last active June 26, 2024 00:09
Show Gist options
  • Save nadiaholmquist/885423e0c9cc08af611348134bd8cb3d to your computer and use it in GitHub Desktop.
Save nadiaholmquist/885423e0c9cc08af611348134bd8cb3d to your computer and use it in GitHub Desktop.
Permanent setup for sudo with Touch ID for macOS

Permanent sudo Touch ID setup for macOS

Want to use Touch ID with sudo but annoyed that the change gets reset every time macOS updates? Here's a hacky solution to fix that!

Installation

  1. Compile pam-touchid-setup.c
    clang -o pam-touchid-setup pam-touchid-setup.c
    
  2. Copy the binary and set its permissions
    sudo cp pam-touchid-setup /usr/local/bin/
    sudo chown root:wheel /usr/local/bin/pam-touchid-setup
    sudo chmod 755 /usr/local/bin/pam-touchid-setup
  3. Open System Preferences -> Security and Privacy, go to the Privacy tab and add /usr/local/bin/pam-touchid-setup under "Full disk access"
  4. Copy sh.nhp.PAMTouchIDSetup.plist into /Library/LaunchDaemons/
  5. Activate the LaunchDaemon
    sudo launchctl load -w /Library/LaunchDaemons/sh.nhp.PAMTouchIDSetup.plist
    
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
const char* tid_line = "auth sufficient pam_tid.so\n";
const char* conf_file = "/etc/pam.d/sudo";
char* new_content;
char* line;
size_t len;
FILE* f;
int main(int argc, char** argv) {
f = fopen(conf_file, "r");
if (!f) {
perror("Could not open config for reading");
return 1;
}
fseek(f, 0, SEEK_END);
new_content = calloc(ftell(f) + strlen(tid_line), sizeof(char));
fseek(f, 0, SEEK_SET);
while (getline(&line, &len, f) != -1) {
if (strcmp(line, tid_line) == 0) {
printf("pam_tid.so already in config, don't need to do anything\n");
return 0;
}
if (strstr(line, "pam_smartcard.so") != NULL) {
strcat(new_content, tid_line);
}
strcat(new_content, line);
}
fclose(f);
f = fopen(conf_file, "w");
if (!f) {
perror("Could not open config for writing");
return 1;
}
fwrite(new_content, strlen(new_content), 1, f);
fclose(f);
return 0;
}
<?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>Label</key>
<string>sh.nhp.PAMTouchIDSetup</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/pam-touchid-setup</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>UserName</key>
<string>root</string>
</dict>
</plist>
@jusefn
Copy link

jusefn commented May 24, 2022

This is amazing, wish i discovered this sooner.

@ThatStella7922
Copy link

Seems to work intermittently on macOS Sequoia, not sure if beta oddities or if Apple is tightening security down

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment