Posted on 08-17-2017 03:26 PM
Greetings JAMF'rs, We are trying to allow standard users to change their passwords, but first you some background: We have re-imaged each machine in our school, setup each account to be assured that each device has hit the JSS Server, setup the account with one standard password(not very secure though), and have Users & Groups, Sharing and Security & Privacy blocked in Sys Prefs.
We are trying to find a script, JAMF sent one option, that asks each user to change their password on their initial login. Problem is, the password can be the same one as before. I would love a script to enforce complexity rules (Alphanumeric, with at least 1 Symbol, Uppercase, and Lowercase and a Number, with minimum of 8 characters)
Has anyone had any success with doing this?
I am not a scripter but I can follow along what is occurring within the script, just no luck in making my basic script work correctly.
Thanks all for any and all help you can send out.
R
Solved! Go to Solution.
Posted on 08-21-2017 07:17 AM
@Gachowski the script sent seemed to work, but only on one of the 2 devices. After a reimage the script does not work at all, even though it says it is completed.
The script used is:
LOGGEDINUSER=$(ls -l /dev/console | awk '{print $3}')
echo "LOGGEDINUSER is: $LOGGEDINUSER"
COMPANY_NAME="KIDSRSU.org" # CHANGE THIS TO YOUR COMPANY NAME
PW_EXPIRE=365 # 90 days password expiration, changed to 365 days - rhoooper081817
MIN_LENGTH=8 # at least 8 chars for password
MIN_NUMERIC=1 # at least 1 number in password
MIN_ALPHA_LOWER=1 # at least 1 lower case letter in password
MIN_UPPER_ALPHA=1 # at least 1 upper case letter in password
exemptAccount1="RSU2Admin" #Exempt account used for remote management. CHANGE THIS TO YOUR EXEMPT ACCOUNT
echo "<dict> <key>policyCategoryAuthentication</key> <array> <dict> <key>policyContent</key> <string>(policyAttributeFailedAuthentications < policyAttributeMaximumFailedAuthentications) OR (policyAttributeCurrentTime > (policyAttributeLastFailedAuthenticationTime + autoEnableInSeconds))</string> <key>policyIdentifier</key> <string>Authentication Lockout</string> <key>policyParameters</key> <dict> <key>autoEnableInSeconds</key> <integer>$LOCKOUT</integer> <key>policyAttributeMaximumFailedAuthentications</key> <integer>$MAX_FAILED</integer> </dict> </dict> </array>
<key>policyCategoryPasswordChange</key> <array> <dict> <key>policyContent</key> <string>policyAttributeCurrentTime > policyAttributeLastPasswordChangeTime + (policyAttributeExpiresEveryNDays 24 60 * 60)</string> <key>policyIdentifier</key> <string>Change every $PW_EXPIRE days</string> <key>policyParameters</key> <dict> <key>policyAttributeExpiresEveryNDays</key> <integer>$PW_EXPIRE</integer> </dict> </dict> </array>
<key>policyCategoryPasswordContent</key> <array> <dict> <key>policyContent</key> <string>policyAttributePassword matches '.{$MIN_LENGTH,}+'</string> <key>policyIdentifier</key> <string>Has at least $MIN_LENGTH characters</string> <key>policyParameters</key> <dict> <key>minimumLength</key> <integer>$MIN_LENGTH</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>policyAttributePassword matches '(.[0-9].){$MIN_NUMERIC,}+'</string> <key>policyIdentifier</key> <string>Has a number</string> <key>policyParameters</key> <dict> <key>minimumNumericCharacters</key> <integer>$MIN_NUMERIC</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>policyAttributePassword matches '(.[a-z].){$MIN_ALPHA_LOWER,}+'</string> <key>policyIdentifier</key> <string>Has a lower case letter</string> <key>policyParameters</key> <dict> <key>minimumAlphaCharactersLowerCase</key> <integer>$MIN_ALPHA_LOWER</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>policyAttributePassword matches '(.[A-Z].){$MIN_UPPER_ALPHA,}+'</string> <key>policyIdentifier</key> <string>Has an upper case letter</string> <key>policyParameters</key> <dict> <key>minimumAlphaCharacters</key> <integer>$MIN_UPPER_ALPHA</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>policyAttributePassword matches '(.[^a-zA-Z0-9].){$MIN_SPECIAL_CHAR,}+'</string> <key>policyIdentifier</key> <string>Has a special character</string> <key>policyParameters</key> <dict> <key>minimumSymbols</key> <integer>$MIN_SPECIAL_CHAR</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>none policyAttributePasswordHashes in policyAttributePasswordHistory</string> <key>policyIdentifier</key> <string>Does not match any of last $PW_HISTORY passwords</string> <key>policyParameters</key> <dict> <key>policyAttributePasswordHistoryDepth</key> <integer>$PW_HISTORY</integer> </dict> </dict>
</array>
</dict>" > /private/var/tmp/pwpolicy.plist
if [ "$LOGGEDINUSER" != "$exemptAccount1" ]; then chown $LOGGEDINUSER:staff /private/var/tmp/pwpolicy.plist chmod 644 /private/var/tmp/pwpolicy.plist
# clear account policy before loading a new one pwpolicy -u $LOGGEDINUSER -clearaccountpolicies pwpolicy -u $LOGGEDINUSER -setaccountpolicies /private/var/tmp/pwpolicy.plist
elif [ "$LOGGEDINUSER" == "$exemptAccount1" ]; then
echo "Currently $exemptAccount1 is logged in and the password policy was NOT set. This script can only be run if the standard computer user is logged in."
rm -f /private/var/tmp/pwpolicy.plist
exit 1
fi
rm -f /private/var/tmp/pwpolicy.plist
echo "Password policy successfully applied. Run "sudo pwpolicy -u <user> -getaccountpolicies" to see it."
exit 0
Posted on 08-17-2017 07:28 PM
Have you thought of using the config profile for enforcing password complexity?
Also if you can pass the script from jamf we can have a crack at it.
Posted on 08-18-2017 10:21 AM
So like Antonio_ong said use profiles they are the easiest and Apple 1st choice.. Here is the second Apple "way"
https://www.jamf.com/jamf-nation/discussions/18574/user-password-policies-on-non-ad-machines
and how to force a password change..
#!/bin/sh
pwpolicy -u $3 -setpolicy "newPasswordRequired=1"
C
Posted on 08-18-2017 12:19 PM
Thanks #antonio_ong for the update.
Thanks #gachowskiI will have to look at that link.
Sorry I forgot to add the script being used: 'pwpolicy -setglobalpolicy "newPasswordRequired=1" ; sudo pkill loginwindow'
We had to use globalpolicy as the other method did not prompt at all for a password change. The other item I noticed was it also asks for the hidden admin to change their password as well if they log into the device.
The complexity, the only location I have seen that to be set is in pre-stage. Is there another location?
Posted on 08-21-2017 07:17 AM
@Gachowski the script sent seemed to work, but only on one of the 2 devices. After a reimage the script does not work at all, even though it says it is completed.
The script used is:
LOGGEDINUSER=$(ls -l /dev/console | awk '{print $3}')
echo "LOGGEDINUSER is: $LOGGEDINUSER"
COMPANY_NAME="KIDSRSU.org" # CHANGE THIS TO YOUR COMPANY NAME
PW_EXPIRE=365 # 90 days password expiration, changed to 365 days - rhoooper081817
MIN_LENGTH=8 # at least 8 chars for password
MIN_NUMERIC=1 # at least 1 number in password
MIN_ALPHA_LOWER=1 # at least 1 lower case letter in password
MIN_UPPER_ALPHA=1 # at least 1 upper case letter in password
exemptAccount1="RSU2Admin" #Exempt account used for remote management. CHANGE THIS TO YOUR EXEMPT ACCOUNT
echo "<dict> <key>policyCategoryAuthentication</key> <array> <dict> <key>policyContent</key> <string>(policyAttributeFailedAuthentications < policyAttributeMaximumFailedAuthentications) OR (policyAttributeCurrentTime > (policyAttributeLastFailedAuthenticationTime + autoEnableInSeconds))</string> <key>policyIdentifier</key> <string>Authentication Lockout</string> <key>policyParameters</key> <dict> <key>autoEnableInSeconds</key> <integer>$LOCKOUT</integer> <key>policyAttributeMaximumFailedAuthentications</key> <integer>$MAX_FAILED</integer> </dict> </dict> </array>
<key>policyCategoryPasswordChange</key> <array> <dict> <key>policyContent</key> <string>policyAttributeCurrentTime > policyAttributeLastPasswordChangeTime + (policyAttributeExpiresEveryNDays 24 60 * 60)</string> <key>policyIdentifier</key> <string>Change every $PW_EXPIRE days</string> <key>policyParameters</key> <dict> <key>policyAttributeExpiresEveryNDays</key> <integer>$PW_EXPIRE</integer> </dict> </dict> </array>
<key>policyCategoryPasswordContent</key> <array> <dict> <key>policyContent</key> <string>policyAttributePassword matches '.{$MIN_LENGTH,}+'</string> <key>policyIdentifier</key> <string>Has at least $MIN_LENGTH characters</string> <key>policyParameters</key> <dict> <key>minimumLength</key> <integer>$MIN_LENGTH</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>policyAttributePassword matches '(.[0-9].){$MIN_NUMERIC,}+'</string> <key>policyIdentifier</key> <string>Has a number</string> <key>policyParameters</key> <dict> <key>minimumNumericCharacters</key> <integer>$MIN_NUMERIC</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>policyAttributePassword matches '(.[a-z].){$MIN_ALPHA_LOWER,}+'</string> <key>policyIdentifier</key> <string>Has a lower case letter</string> <key>policyParameters</key> <dict> <key>minimumAlphaCharactersLowerCase</key> <integer>$MIN_ALPHA_LOWER</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>policyAttributePassword matches '(.[A-Z].){$MIN_UPPER_ALPHA,}+'</string> <key>policyIdentifier</key> <string>Has an upper case letter</string> <key>policyParameters</key> <dict> <key>minimumAlphaCharacters</key> <integer>$MIN_UPPER_ALPHA</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>policyAttributePassword matches '(.[^a-zA-Z0-9].){$MIN_SPECIAL_CHAR,}+'</string> <key>policyIdentifier</key> <string>Has a special character</string> <key>policyParameters</key> <dict> <key>minimumSymbols</key> <integer>$MIN_SPECIAL_CHAR</integer> </dict> </dict>
<dict> <key>policyContent</key> <string>none policyAttributePasswordHashes in policyAttributePasswordHistory</string> <key>policyIdentifier</key> <string>Does not match any of last $PW_HISTORY passwords</string> <key>policyParameters</key> <dict> <key>policyAttributePasswordHistoryDepth</key> <integer>$PW_HISTORY</integer> </dict> </dict>
</array>
</dict>" > /private/var/tmp/pwpolicy.plist
if [ "$LOGGEDINUSER" != "$exemptAccount1" ]; then chown $LOGGEDINUSER:staff /private/var/tmp/pwpolicy.plist chmod 644 /private/var/tmp/pwpolicy.plist
# clear account policy before loading a new one pwpolicy -u $LOGGEDINUSER -clearaccountpolicies pwpolicy -u $LOGGEDINUSER -setaccountpolicies /private/var/tmp/pwpolicy.plist
elif [ "$LOGGEDINUSER" == "$exemptAccount1" ]; then
echo "Currently $exemptAccount1 is logged in and the password policy was NOT set. This script can only be run if the standard computer user is logged in."
rm -f /private/var/tmp/pwpolicy.plist
exit 1
fi
rm -f /private/var/tmp/pwpolicy.plist
echo "Password policy successfully applied. Run "sudo pwpolicy -u <user> -getaccountpolicies" to see it."
exit 0