Posted on 07-28-2016 08:21 AM
Does anyone know of an accurate way (by script or command) to determine if a user has logged into a particular Mac in the past or not?
Im experimenting with a "first-run" type of script that would run once per user per computer, but I only want it to affect new local users login in for the very first time (not existing local accounts). Long story on what Im trying to achieve here.
Posted on 07-28-2016 08:49 AM
Can you talk a bit more about what you want to accomplish? Specifically, it sounds like you might NOT want this script to run against users who have logged in prior to implementing and deploying it.
I also assume you're deleting accounts/folders periodically from /Users, hence you can't just check the creation date of their home folder.
I assume we're talking about network users here... Depending upon HOW the network account login is configured you could check their ID against the result of "dscl localonly -list /Local/Default/Users" - although by the time the script runs from their account it might be too late; you might need to establish this list ahead of time with a different script (run at startup / user logout) and have each user update it on first logon accordingly.
Hope that helps!
g=
Posted on 07-28-2016 08:56 AM
Hmm. Well, you might be able to grab the logged in username and check the last command for lines that begin with that account name, and do a count. if the total is greater than 1, then I'd assume its not the first time the account has logged into the Mac. For example,
#!/bin/bash
sleep 3
loggedInUser=$(stat -f%Su /dev/console)
loginCount=$(last -t console | grep "^${loggedInUser}" | awk 'END {print NR}')
if ((loginCount>1)); then
echo "Not first login. Exiting..."
exit 0
else
echo "First login. Continuing..."
## Do something here
fi
To be 100% fair, I haven't tested this against an actual first login, so I don't know for sure how well something like this would work. I assume it would but you'd need to test that out for yourself. The sleep at the beginning is just to ensure the login has time to complete and register with the last command before it runs.
Posted on 07-28-2016 08:57 AM
The "big picture" on my scenario is too complicated (and too boring) to go into too much detail on. It tentacles in various directions too, depending on how I try and leverage it.
In a nutshell, it will be the key in determining if certain Finder and Dock settings will or will not be applied at login time. I have a contigent of older users on exisitng Macs who Im not going to affect, but going forward all new Macs and (new users on exisitng Macs) will be affected. The magic will be dertiming if they are logging in for the first time or not.
I'm not deleting user accounts of homedirs. Not data loss concerns here.
I simply want to determine if a user who happens to be logging into a Mac has ever logged into it before.
I'm referring to Active Directory users (who are managed mobile accounts and get local accounts created in OS X's dscl). They all have local homedirs in /Users.
I'm referring to user logging into GUI console sessions (i.e.; not SSH sessions).
One idea I am pondering...
At login time, examine the user's homedir in /Users to verify its creation date, and then make a caluation to the affect of "if the homedir is older than, say, ~1 hour, then exit the script (safe bet that the user is not logging in for the very time), otherwise continue with other tasks in the script as needed.
But Im not sure Id reliably capture (and trust) homedir date stamps. I have played with /usr/bin/stat and other tools but am not getting the right values to make a comparaison to.
Posted on 07-28-2016 08:57 AM
Since the post doesn't go into specifics on what the actual goal is. I do have a script that can check if a user has logged into a system or not and has exclusions for service and local accounts.
This script was to add a mobile user network admin account when they log in with there standard account. It could certianly be adapted for other uses.
#!/bin/sh
### Script Variables###
CD="/Applications/utilities/CocoaDialog.app/Contents/MacOS/CocoaDialog"
userName=$(ls -l /dev/console | awk '{ print $3 }')
adminusername="$userName"admin
UID1=$(id -u $userName)
if [[ "$UID1" -lt 1000 ]]; then
echo ""$userName" is a local user. This script will now quit"
exit 0
else
if [[ $currentUser == *"admin"* ]]; then
echo ""$currentUser" is an admin account. This script will now quit"
exit 0
else
if [[ $userName == *"adobeinstall"* ]]; then
echo "The adobeinstall account is a service account. This script will now quit"
exit 0
else
if [[ -e /Users/"$adminusername" ]]; then
echo ""$userName" already has an admin named "$adminusername" on this system"
exit 0
else
if [[ "$UID1" -ge 1000 ]];
then echo "User "$userName" is an Active Directory account"
/System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -v -n "$adminusername" -h /Users/"$adminusername"
dscl . -append /Groups/admin GroupMembership "$adminusername"
fi
fi
fi
fi
Posted on 07-28-2016 09:33 AM
I think we're headed in the right direction here... and another recent thread seems to have some good - but different - hints too:
https://jamfnation.jamfsoftware.com/discussion.html?id=4502#responseChild21985
Thank you for clarifying what you needed... besides mostly enjoying the power of jamfnation to bounce ideas off the heads of others!
Posted on 07-28-2016 12:16 PM
Im getting closer.
The -mtime switch for the /usr/bin/find command is helpful! Never used it before. May come in handy.
Thank you @Sterritt
Posted on 07-28-2016 12:41 PM
FYI to all but specifically @mm2270 Apple has deprecated the last and ac commands so while they continue to work I have seen cases where they stop functioning and are not promised to continue to. Guidance is to pull the login and logout data from these commands respectively:
syslog -F raw -k Facility com.apple.system.lastlog
syslog -F raw -k Facility com.apple.system.utmpx
It is far from ideal and as nice as last. I have an ask in for them to update or recreate what the last command can report on. Just thought I'd give you a heads up.
Posted on 07-28-2016 01:16 PM
Paydirt. Maybe.
Running the /usr/bin/last command and filtering on the current console might be helpful. If the user isn't in the last log then it can be assumed that the user is logging in for the first time. That's all I need. No-brainer. I couldn't see the forest from the trees.
I wasnt aware that Apple has deprecated /usr/bin/last in Darwin. Wonder if I should play Russian Roulette with /usr/bin/last or not.
@iJake How did find out that /usr/bin/last is deprecated?
Posted on 08-01-2016 06:55 AM
I have found that /usr/bin/last cant be trusted. A "quantum" thing happens - A new user logs in and my script runs. Script queries /usr/bin/last and sees that the new user just logged in (albeit just a few seconds prior), therefore the script thinks the user is an "exisitng user" and not a new user and exits. Its sort of a race condition. Id have get get more surgical at the last data (filter and examine timestamps etc)
@mm2270 sample above (looks for greater than 1 entry in /usr/bin/last ) isnt working for me. It thinks ALL users are new users. Need to play with it more...
Now I'm playing with /usr/bin/syslog (per @iJake advice) , but I suspect that syslog may not be helpful either because the logs can be rolled-up, delete, etc.
Posted on 08-01-2016 07:36 AM
Hey @dstranathan you may want to take a look at the script I posted above last week. You'll see that I do a count of the number of 'console' entries that have the logged in users name in them from the last
command. If the count is greater than 1, then it's not the first login. If it's 1, then it is the first login.
You'll never be able to make a login script runner faster than the last command will write in the login entry. There should be no need to do something like look at the login time stamps and compare them.
Edit: Looks like you edited your post since I posted. I'm not sure why its not working for you, since I actually did get around to trying the script on a Mac. I created a new user account, one that was never on it before, and logged in and had the script run. It echoed back it was the first login. I then logged out, logged in under a different account and then back into the new account and ran the script again and it reported it was not the first login. So, not sure what the deal is, but it worked for me. Are you certain the accounts you're testing it under have never been on the Mac before? If its an account that was created, then later deleted and recreated on that same Mac, its not going to work.
Posted on 08-01-2016 07:39 AM
The below one-liner might help in all of this as it pulls the date the account was created.
dscl . readpl /Users/"$USERNAME" accountPolicyData creationTime | awk -F: '{ print $2 }' | tr -d " " | cut -d "." -f 1
Posted on 08-01-2016 11:56 AM
I appears to be working when ran as a script from a policy, but when running locally as me it yields different results.
Thanks again sir.
Posted on 08-04-2016 06:31 AM
@mm2270 I have determined that the following command doesnt work on all my Macs:
last -t console
The "console" switch fails to show me correct information. It works fine wth ttys001 (Terminal or SSH) sessions, but not GUI console sessions.
The last command is a strange beast. Definitely needs to run as admin rights.
Posted on 08-04-2016 07:46 AM
@dstranathan Yes, I mentioned earlier last has been deprecated by Apple and is not promised to work. See my post above.
Posted on 08-04-2016 08:02 AM
@iJake Where did you get your information that last was depreciated? I have an Apple support request open to find out why it's not working on some machines and never got that info. I also didn't get the guidance on using syslog. Where did that guidance come from? Apple? What branch? Finally, the syslog commands you gave above generated no output on my machine - you are able to see login history using that command?
Posted on 08-05-2016 09:18 AM
@thoule It was given to me by AppleCare Enterprise Support. More accurately, wtmp is what is deprecated and that is what last uses. It was replaced with asl. See this exchange:
The man page for wtmp indicates that this system is deprecated. The commands replying on this file do function, but as you have seen they sometimes will only report partial information.The appropriate replacement would be using syslog to access the asl logs, which do contain this information. An example command would be:This is admittedly more information to have to dig through, and probably less convenient than the traditional commands. However if this is being automated you should be able to narrow it down to the information you want in your report.syslog -F raw -k Facility com.apple.system.lastlog
Accessing the asl logs with syslog or asl is the intended method to get this information on a system. As an example of how this output can be reduced to something more readable, this command line prints out the unix timestamps and short usernames.Another option would be to periodically run the commands and log their output to your own log file over time. It would likely be an even more involved solution to use auditd, however I mention it because it would be one other method to gather login information.syslog -F raw -k Facility com.apple.system.lastlog | awk '{ print substr($4,1,length($4)-1) " " substr($28,1,length($28)-1) }'