#!/bin/bash
##########################################################################################################
## Purpose:  Create a pwpolicy XML file based upon variables and options included below.
##          Policy is applied and then file gets deleted. Use &#34;sudo pwpolicy -u &lt;user&gt; -getaccountpolicies&#34;
##          to see it, and &#34;sudo pwpolicy -u &lt;user&gt; -clearaccountpolicies&#34; to clear it.
## 
## Usage:   Edit variables in Variable flowerbox below.
##          Then run as a policy from Casper, or standalone as root.
##
## Tested on: OS X 10.10 and 10.11
##
#########################################################################################################

# get logged-in user and assign it to a variable
LOGGEDINUSER=$(ls -l /dev/console | awk &#39;{print $3}&#39;)

echo &#34;LOGGEDINUSER is: $LOGGEDINUSER&#34;

##############################################################################
# Variables for script and commands generated below.
#
# EDIT AS NECESSARY FOR YOUR OWN PASSWORD POLICY
# AND COMPANY INFORMATION
#
COMPANY_NAME=&#34;1kosmos&#34;  # CHANGE THIS TO YOUR COMPANY NAME
LOCKOUT=300                     # 5min lockout
MAX_FAILED=5                   # 5 max failed logins before locking
PW_EXPIRE=90                    # 90 days password expiration
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
MIN_SPECIAL_CHAR=1              # at least one special character in password
PW_HISTORY=5                   # remember last 10 passwords

exemptAccount1=&#34;administrator&#34;          #Exempt account used for remote management. CHANGE THIS TO YOUR EXEMPT ACCOUNT
#
##############################################################################

#################################################
##### create pwpolicy.plist in /private/var/tmp
# Password policy using variables above is:
# Change as necessary in variable flowerbox above
# --------------------------------------------------
# pw&#39;s must be at least 8 chars
# pw&#39;s must have at least 1 lower case letter
# pw&#39;s must have at least 1 upper case letter
# pw&#39;s must have at least 1 special non-alpha/non-numeric character
# pw&#39;s must have at least 1 number
# can&#39;t use any of the previous 10 passwords
# pw&#39;s expire at 90 days
# 10 failed successive login attempts results in a 300sec lockout, then auto enables

echo &#34;&lt;dict&gt;
 &lt;key&gt;policyCategoryAuthentication&lt;/key&gt;
  &lt;array&gt;
   &lt;dict&gt;
    &lt;key&gt;policyContent&lt;/key&gt;
     &lt;string&gt;(policyAttributeFailedAuthentications &amp;lt; policyAttributeMaximumFailedAuthentications) OR (policyAttributeCurrentTime &amp;gt; (policyAttributeLastFailedAuthenticationTime + autoEnableInSeconds))&lt;/string&gt;
    &lt;key&gt;policyIdentifier&lt;/key&gt;
     &lt;string&gt;Authentication Lockout&lt;/string&gt;
    &lt;key&gt;policyParameters&lt;/key&gt;
  &lt;dict&gt;
  &lt;key&gt;autoEnableInSeconds&lt;/key&gt;
   &lt;integer&gt;$LOCKOUT&lt;/integer&gt;
   &lt;key&gt;policyAttributeMaximumFailedAuthentications&lt;/key&gt;
   &lt;integer&gt;$MAX_FAILED&lt;/integer&gt;
  &lt;/dict&gt;
 &lt;/dict&gt;
 &lt;/array&gt;


 &lt;key&gt;policyCategoryPasswordChange&lt;/key&gt;
  &lt;array&gt;
   &lt;dict&gt;
    &lt;key&gt;policyContent&lt;/key&gt;
     &lt;string&gt;policyAttributeCurrentTime &amp;gt; policyAttributeLastPasswordChangeTime + (policyAttributeExpiresEveryNDays * 24 * 60 * 60)&lt;/string&gt;
    &lt;key&gt;policyIdentifier&lt;/key&gt;
     &lt;string&gt;Change every $PW_EXPIRE days&lt;/string&gt;
    &lt;key&gt;policyParameters&lt;/key&gt;
    &lt;dict&gt;
     &lt;key&gt;policyAttributeExpiresEveryNDays&lt;/key&gt;
      &lt;integer&gt;$PW_EXPIRE&lt;/integer&gt;
    &lt;/dict&gt;
   &lt;/dict&gt;
  &lt;/array&gt;


  &lt;key&gt;policyCategoryPasswordContent&lt;/key&gt;
 &lt;array&gt;
  &lt;dict&gt;
   &lt;key&gt;policyContent&lt;/key&gt;
    &lt;string&gt;policyAttributePassword matches &#39;.{$MIN_LENGTH,}+&#39;&lt;/string&gt;
   &lt;key&gt;policyIdentifier&lt;/key&gt;
    &lt;string&gt;Has at least $MIN_LENGTH characters&lt;/string&gt;
   &lt;key&gt;policyParameters&lt;/key&gt;
   &lt;dict&gt;
    &lt;key&gt;minimumLength&lt;/key&gt;
     &lt;integer&gt;$MIN_LENGTH&lt;/integer&gt;
   &lt;/dict&gt;
  &lt;/dict&gt;


  &lt;dict&gt;
   &lt;key&gt;policyContent&lt;/key&gt;
    &lt;string&gt;policyAttributePassword matches &#39;(.*[0-9].*){$MIN_NUMERIC,}+&#39;&lt;/string&gt;
   &lt;key&gt;policyIdentifier&lt;/key&gt;
    &lt;string&gt;Has a number&lt;/string&gt;
   &lt;key&gt;policyParameters&lt;/key&gt;
   &lt;dict&gt;
   &lt;key&gt;minimumNumericCharacters&lt;/key&gt;
    &lt;integer&gt;$MIN_NUMERIC&lt;/integer&gt;
   &lt;/dict&gt;
  &lt;/dict&gt;


  &lt;dict&gt;
   &lt;key&gt;policyContent&lt;/key&gt;
    &lt;string&gt;policyAttributePassword matches &#39;(.*[a-z].*){$MIN_ALPHA_LOWER,}+&#39;&lt;/string&gt;
   &lt;key&gt;policyIdentifier&lt;/key&gt;
    &lt;string&gt;Has a lower case letter&lt;/string&gt;
   &lt;key&gt;policyParameters&lt;/key&gt;
   &lt;dict&gt;
   &lt;key&gt;minimumAlphaCharactersLowerCase&lt;/key&gt;
    &lt;integer&gt;$MIN_ALPHA_LOWER&lt;/integer&gt;
   &lt;/dict&gt;
  &lt;/dict&gt;


  &lt;dict&gt;
   &lt;key&gt;policyContent&lt;/key&gt;
    &lt;string&gt;policyAttributePassword matches &#39;(.*[A-Z].*){$MIN_UPPER_ALPHA,}+&#39;&lt;/string&gt;
   &lt;key&gt;policyIdentifier&lt;/key&gt;
    &lt;string&gt;Has an upper case letter&lt;/string&gt;
   &lt;key&gt;policyParameters&lt;/key&gt;
   &lt;dict&gt;
   &lt;key&gt;minimumAlphaCharacters&lt;/key&gt;
    &lt;integer&gt;$MIN_UPPER_ALPHA&lt;/integer&gt;
   &lt;/dict&gt;
  &lt;/dict&gt;


  &lt;dict&gt;
   &lt;key&gt;policyContent&lt;/key&gt;
    &lt;string&gt;policyAttributePassword matches &#39;(.*[^a-zA-Z0-9].*){$MIN_SPECIAL_CHAR,}+&#39;&lt;/string&gt;
   &lt;key&gt;policyIdentifier&lt;/key&gt;
    &lt;string&gt;Has a special character&lt;/string&gt;
   &lt;key&gt;policyParameters&lt;/key&gt;
   &lt;dict&gt;
   &lt;key&gt;minimumSymbols&lt;/key&gt;
    &lt;integer&gt;$MIN_SPECIAL_CHAR&lt;/integer&gt;
   &lt;/dict&gt;
  &lt;/dict&gt;


  &lt;dict&gt;
   &lt;key&gt;policyContent&lt;/key&gt;
    &lt;string&gt;none policyAttributePasswordHashes in policyAttributePasswordHistory&lt;/string&gt;
   &lt;key&gt;policyIdentifier&lt;/key&gt;
    &lt;string&gt;Does not match any of last $PW_HISTORY passwords&lt;/string&gt;
   &lt;key&gt;policyParameters&lt;/key&gt;
   &lt;dict&gt;
    &lt;key&gt;policyAttributePasswordHistoryDepth&lt;/key&gt;
     &lt;integer&gt;$PW_HISTORY&lt;/integer&gt;
   &lt;/dict&gt;
  &lt;/dict&gt;

 &lt;/array&gt;
&lt;/dict&gt;&#34; &gt; ~/pwpolicy.plist
##### end of pwpolicy.plist generation script
###################################################

#Check for non-admin account before deploying policy
if [ &#34;$LOGGEDINUSER&#34; != &#34;$exemptAccount1&#34; ]; then
  chown $LOGGEDINUSER:staff ~/pwpolicy.plist
  chmod 644 ~/pwpolicy.plist

  # clear account policy before loading a new one
  pwpolicy -u $LOGGEDINUSER -clearaccountpolicies 
  pwpolicy -u $LOGGEDINUSER -setaccountpolicies ~/pwpolicy.plist

elif [ &#34;$LOGGEDINUSER&#34; == &#34;$exemptAccount1&#34; ]; then
    echo &#34;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.&#34;
    rm -f ~/pwpolicy.plist
    exit 1
fi

#delete staged pwploicy.plist
rm -f ~/pwpolicy.plist

echo &#34;Password policy successfully applied. Run \&#34;sudo pwpolicy -u &lt;user&gt; -getaccountpolicies\&#34; to see it.&#34;
exit 0
