Help with script to delete "Local Items" keychain

michaelherrick
New Contributor III

Our users frequently encounter an issue where at login, they are repeatedly asked for the "Local Items" keychain password. Apple details the problem and solution here, which works well , but I would love to script it and make it a Self Service or pushable item.

I wrote the following simple Bash script, which works, however only if ran locally:

#!/bin/bash

if test -e ~/library/keychains/????????-????-????-????-????????????; then
    echo "Local Items keychain found"
    rm -rf ~/library/keychains/????????-????-????-????-????????????
else
    echo "No local items keychain found"
    exit 1
fi

This is because Casper runs scripts as root, so if pushed through Remote it won't do anything to the logged in user's Keychain folder. I took a look at this discussion on JAMFnation and wrote the following, but it doesn't work whether ran locally or remotely:

#!/bin/bash

current_user=finger -s -l | grep Login | cut -c 8-25
if test -e /Users/$current_user/library/keychains/????????-????-????-????-????????????; then
    echo "Local Items keychain found"
    rm -rf /Users/$current_user/library/keychains/????????-????-????-????-????????????
else
    echo "No local items keychain found"
    exit 1
fi

If I run the

finger -s -l | grep Login | cut -c 8-25

section in Terminal it echoes my username just fine, but it seems like it doesn't store that variable and regardless of whether or not the Local Items folder is present, the script just echoes my username then "No local items keychain found". I know that normally you can use the $3 variable as the user home, but this only works with login/out hooks, and I would like this to be usable in self service or Remote. Does anyone have any ideas on how to fix this script? Any help is much appreciated. I also realize that the folder name for the Local Items is actually the UUID and not random characters, so the whole business with ? wildcards is kind of kludgey.

1 ACCEPTED SOLUTION

strider_knh
Contributor II

You can use the system variable $User in the path. $User is the short name for the user that is currently logged into the computer. Running a script as root while a user is logged in does not change this variable.

If the station is bound to AD and you are using AD logins for Self Service you could also add the script to Self Service for whoever needs it. This would give you access to the variable $3 for the user ID that logged into Self Service.

One of these methods would allow you to specify the location of the keychain to delete.

Example:
/Users/$USER or $3/library/keychains/????????-????-????-????-????????????

View solution in original post

19 REPLIES 19

strider_knh
Contributor II

You can use the system variable $User in the path. $User is the short name for the user that is currently logged into the computer. Running a script as root while a user is logged in does not change this variable.

If the station is bound to AD and you are using AD logins for Self Service you could also add the script to Self Service for whoever needs it. This would give you access to the variable $3 for the user ID that logged into Self Service.

One of these methods would allow you to specify the location of the keychain to delete.

Example:
/Users/$USER or $3/library/keychains/????????-????-????-????-????????????

emily
Valued Contributor III
Valued Contributor III

Or how about

username=`who | grep "console" | awk '{print $1}'`

Which would then be

$username/Library/Keychains

michaelherrick
New Contributor III

That works, thank you!

mikeh
Contributor II

There is a small, easily-overlooked error in your second example script. The assignment of the command output to the variable current_user isn't quoted:

current_user=`finger -s -l | grep Login | cut -c 8-25`

It should work fine after that change. The other suggestions are also great - I use Emily's method all the time.

Cheers!

zanb
New Contributor III

Sometimes OS X will save multiple folders in the "X8X8X8X8-X4X4-X4X4-X4X4-X12X12X12X12" format. This script should help you whether you need to delete one or many folders with the same naming structure.

Disclaimer: Because this script will attempt to delete data, run this script on a test machine before using it in a production environment. I've only tested it on my personal machine. Thank you

#!/bin/bash
# For each folder within ~/Library/Keychain, evaluate the name.
for LKEY in /Users/"${3}"/Library/Keychains/*;do 
  # This validates that the folder is in X8X8X8X8-X4X4-X4X4-X4X4-X12X12X12X12 format.
  # If it matches the naming convention the script will delete it. 
  if [[ "${LKEY}" =~ [0-9A-Z-]{8}[0-9A-Z-]{5}[0-9A-Z-]{5}[0-9A-Z-]{5}[0-9A-Z-]{13} ]];then 
    echo "Removing $LKEY"
    rm -rf "${LKEY}"
  fi
done
exit

donmontalvo
Esteemed Contributor III

Lots of ways to skin the cat. At a previous gig our UNIX team used to bet lunch on which option would show the shortest average time:

$ time finger -s -l | grep Login | cut -c 8-25
jdoe                

real    0m0.924s
user    0m0.595s
sys     0m0.333s
$

vs

$ time who | grep "console" | cut -d " " -f1
jdoe

real    0m0.004s
user    0m0.003s
sys     0m0.005s
$ time ls -l /dev/console | cut -d " " -f4
jdoe

real    0m0.005s
user    0m0.002s
sys     0m0.004s
$ time stat -f%Su /dev/console
jdoe

real    0m0.004s
user    0m0.001s
sys     0m0.002s
$ time who | grep "console" | awk '{print $1}'
jdoe

real    0m0.005s
user    0m0.004s
sys     0m0.006s
$
--
https://donmontalvo.com

ClassicII
Contributor III

We have seen this for users who have changes their password outside the system.

If the user is prompted for the "Local Items" keychain we have had some luck with the user typing in the old password which will then sync the local items keychain.

Even if that does not work you guys have posted up some great info!

strider_knh
Contributor II

Our users login with AD accounts and if they forget their password it is changed in AD. The next time they log into their Mac their new password will not unlock the keychain and they continually get pop-ups.

This has been very annoying this year, both teachers and especially students can't seem to remember their passwords. Password gets changed and then they receive this pop-up.

notverypc
New Contributor III

Worth looking at ADPassMon as well:
ADPassmon

We use it with our staff.

Stubakka
Contributor II

I also want to implement a self service item for resolving the local item keychain issues after a password change that did not take place from the System itself. I have also put ADpassmon on systems and have had good feedback from users using it. Has anyone implemented both in their environment ? If so what method did you use to do so?

FoxSports
New Contributor

is this the correct final format of the script?

!/bin/bash

current_user=finger -s -l | grep Login | cut -c 8-25
if test -e /Users/$User/library/keychains/????????-????-????-????-????????????; then echo "Local Items keychain found" rm -rf /Users/$User/library/keychains/????????-????-????-????-????????????
else echo "No local items keychain found" exit 1
fi

itupshot
Contributor II

@notverypc ADPassMon can sync the Login keychain, but doesn't sync the Local Items keychain.

We've deployed it to all our Macs, but people are still having Local Items keychain popups.

I'll have to experiment with some of the scripts on this thread as an alternative. Does the machine need to restart after running these scripts? You have to do that if you delete the folder manually.

notverypc
New Contributor III

@itupshot Unfortunately I'm not using ADPassMon at the moment, we currently ave no requirement for it.
You may want to look at NoMAD it may suit your needs better.

bentoms
Release Candidate Programs Tester

@itupshot i'd second a look at NoMAD.

I'm hoping to do one more release of ADPassMon, but there are a heap of changes needed for Sierra & I no longer have AD.

There's a private API I hope to leverage in an ADPassMon update that would sync the login password with local items. Just have no ETA as to when I can do that.

mrheathjones
New Contributor III

I wrote my script in AppleScript but here is the main logic for blowing away the local items keychain. I haven't had to use it much but here is a snippet of what worked for me.

on getLocalItems() set localItems to do shell script "system_profiler SPHardwareDataType | grep 'Hardware UUID' | awk '{print $3}'"
end getLocalItems

on deleteLocalItems() try do shell script "rm -rf ~/Library/Keychains/" & localItems & "/" end try
end deleteLocalItems

on rebootNow() ------Modify this-------- tell application "System Events" to restart
end rebootNow

getLocalItems()
deleteLocalItems()
rebootNow()

burdett
Contributor II

Thanks @mrheathjones, The script I have been using that was posted by @zanb had quit working for me. I used your command to get the Hardware UUID and modified @zanb script to match the folder name of the local items keychain and it seems to be working again. Need to do some more testing, to make sure this is working, as this script will attempt to delete data.

#!/bin/sh
# Get the Hardware UUID
hardUUID="system_profiler SPHardwareDataType | grep 'Hardware UUID' | awk '{print $3}'"
# For each folder within ~/Library/Keychain, evaluate the name.
for LKEY in /Users/"${3}"/Library/Keychains/*;do 
  # This validates that the folder matches the Hardware UUID.
  # If it matches the script will delete it. 
  if [[ "${LKEY}" =~ hardUUID ]];then 
    echo "Removing $LKEY"
    rm -rf "${LKEY}"
  fi
done
exit

listec
New Contributor III

Hi @zanb,

Nice script, but I would change the regex to:

  if [[ "${LKEY}" =~ [0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12} ]];then

There were a few problems...
1. the characters are hex so you'll never need G-Z in ' [0-9A-Z] '
2. the '=~' doesn't ignore case unless shopt has been set, so it needs a-f added inside the brackets
3. the final hyphen inside the square brackets allows for it to occur anywhere in the string, so it should only be after each hex set
4. since there are 3 consecutive sets of 4 hex characters followed by a hyphen, they can be grouped

I hope that helps someone!

Brian

ThijsX
Valued Contributor
Valued Contributor

Hi,

Maybe already solved, but this is what we do, just delete the whole keychain when big issues occur.
This script is available for an end user via Self Service.

#!/bin/sh

## Purpose of this script is to reset the login keychain of the user and do a reboot afterwards so that a new keychain will be created on login procedure.

# Removes loginkeychain from current logged in user
rm -Rf /Users/$USER/Library/Keychains/*

# Take a nap
sleep 5

# Pop-up reboot screen
osascript -e 'tell app "loginwindow" to «event aevtrrst»'

exit 0

So maybe a bit "mosterd na de maaltijd" but hope it can help.

Cheers,
Thijs.

ThijsX
Valued Contributor
Valued Contributor

Also,

Maybe this one can also be handy when a user has changed password but has an hold for authentication prompt going on for the network printer.

#!/bin/sh

## Written by Thijs Xhaflaire - 28-09-2017
## Purpose of this script is to delete the old keychain login item, and set the lpadmin cli command to set a new password. This script is combined with a printer mapping script.

#Determine the currently logged in user and save their account name as the loggedInUser
loggedInUser=$( ls -l /dev/console | awk '{print $3}' )

#Delete the specified 'network password' item(s) from the logged in users keychain.
security delete-internet-password -l "PRINTERNAME" /Users/$loggedInUser/Library/Keychains/login.keychain

# Set authentication method to username & password
lpadmin -p CUPSNAME -o printer-is-shared=false -o Finisher="FS534SD" -o auth-info-required=username,password

exit