Tuesday, June 7, 2016

OS X Calendar Server Maintenance and Cleanup

Having some troubles with my calendar server, I decided, it was time for a cleanup.

We are running the Calendar Server on OS X 10.11.x El Capitan.
Server App version 5.1.5.

First thing to do was to reindex the database.

This is my script that does this. I reads a list of the databases and then issues a reindex command to each table:

#!/bin/sh

# Reindex all calendar server databases
# © 2016 kurt hofmann

# Get stat of the calendar server

calStat=`serveradmin status calendar | grep "calendar:calendarState"`

echo "$calStat" | grep "RUNNING" >/dev/null 2>&1
  if [ "$?" -eq "0" ]; then
      echo "Calendar is running"
      CalRunning=true
  else
      echo "Calendar is stopped"
      CalRunning=false
  fi

if $CalRunning ; then
  echo "Stopping calendar server"
  serveradmin stop calendar
fi


# Do the database stuff

export PGDATABASE=caldav
export PGUSER=caldav

# Get list of tables

dbt=`psql -h /var/run/caldavd/PostgresSocket/ << EOF
\d ;
EOF`


dblist=`echo "$dbt" | cut -d "|" -f 2 | grep "^ " | grep -v "^  "`

# With each database in the list, issue a reindex command

for db in $dblist
do

echo "Now reindexing table $db"

dbt=`psql -h /var/run/caldavd/PostgresSocket/ << EOF
REINDEX table $db ;
EOF`

done

# Restart Calendar server if it was running before we started

if $CalRunning ; then
  echo "Starting Calendar"
  serveradmin start calendar
fi

exit 0


Second thing to do was to purge all old calendar entries.

I already had a script that did this, but this no longer worked because this can no longer be done for all users in one go.
The command:

/Applications/Server.app/Contents/ServerRoot/usr/sbin/calendarserver_purge_events
now requires a userid.

So, I first need to read the contents of the databases to find the uids of all the users that actually use the calendar. Then I delete the entries older than 365 days on the calendar.

Then we do the same thing with the attachments.

The script goes like this:

#!/bin/sh

# Using hints from myself ;-) :
#http://osxadmin.blogspot.ch/2015/06/os-x-yosemite-calendar-server-utilites.html

# These are the commands involved:
#/Applications/Server.app/Contents/ServerRoot/usr/sbin/calendarserver_purge_events -nv

#/Applications/Server.app/Contents/ServerRoot/usr/sbin/calendarserver_purge_attachments -nv

#psql -h /var/run/caldavd/PostgresSocket/ --username=caldav

export PGDATABASE=caldav
export PGUSER=caldav

# Get the UIDs of all users

dbt=`psql -h /var/run/caldavd/PostgresSocket/ << EOF
SELECT * FROM calendar_home;
EOF`

theUsers=`echo "$dbt" | cut -d "|" -f 2 | grep "^ " | grep -v "^  "`

# Purge all old data

for uid in $theUsers
do
  echo $uid
  theResult=`/Applications/Server.app/Contents/ServerRoot/usr/sbin/calendarserver_purge_events -u $uid`
  purge_events=`echo "$theResult" | grep "older"`
  echo "$purge_events"
  /Applications/Server.app/Contents/ServerRoot/usr/sbin/calendarserver_purge_attachments -u $uid
  echo "----"
done


Thursday, June 2, 2016

Creating Custom Guest Users on OS X with OS X 10.11 El Capitan

We were using the script by 'rtrouton' from his page  Creating Custom Guest Users on OS X | Der Flounder for our clients up to 10.10 Yosemite.

Unfortunately this script no longer worked when we upgraded to OS X version 10.11 'El Capitan'.

We tried everything, but always ended up with keychain errors.

When logging in, the guest user obviously tried to access keychains which at that moment weren't there or not accessible.

We the tried to revert back to the system guest.
That seemed to work. Until we removed the parental controls from that user at which point the system created a new user named 'Guest1' which had some other problems….

So, after trying around quite a lot, I found a solution.
The changes are actually quite simple. There are tow things that have to be changed:


  1. Add a password for the guest user. The script won't work with empty passwords
  2. The entry in the keychain added has to be accessible to all processes. To allow that the parameter '-A' is added to this step

So this is my version of the script:


#!/bin/bash

# Original script by Noel B. Alonso: https://gist.github.com/nbalonso/5696340
# Modified script by rtrouton: https://github.com/rtrouton/rtrouton_scripts/tree/master/rtrouton_scripts/create_custom_guest_account
#variables
DSCL="/usr/bin/dscl"
SECURITY="/usr/bin/security"
LOGGER="/usr/bin/logger"

# Determine OS version
OSVERS=$(sw_vers -productVersion | awk -F. '{print $2}')

# Set the account shortname
USERNAME="Gast"

# Set the name which is displayed in System Preferences for the account
DISPLAYNAME="Gastbenutzer"

# Set the account's UID
GUESTUID="600"

# Set the account's GID
GUESTGROUPID="600"

if [[ ${OSVERS} -lt 6 ]]; then
  ${LOGGER} -s -t create"${USERNAME}".sh "ERROR: The version of OS X running on this Mac is not supported by this script. User account not created."
fi

if [[ ${OSVERS} -eq 6 ]]; then
${LOGGER} -s -t create"${USERNAME}".sh "INFO: Creating the "${USERNAME}" user account on Mac OS X 10.${OSVERS}.x"
${DSCL} . -create /Users/"${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" UserShell /bin/bash
${DSCL} . -create /Users/"${USERNAME}" RealName "${DISPLAYNAME}"
${DSCL} . -create /Users/"${USERNAME}" UniqueID "${GUESTUID}"
${DSCL} . -create /Users/"${USERNAME}" PrimaryGroupID "${GUESTGROUPID}"
${DSCL} . -create /Users/"${USERNAME}" NFSHomeDirectory /Users/"${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" RecordType dsRecTypeStandard:Users
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_defaultLanguage de
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_guest true
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_writers__defaultLanguage "${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_writers_jpegphoto "${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_writers_LinkedIdentity "${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_writers_picture "${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_writers_UserCertificate "${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" AppleMetaNodeLocation /Local/Default
#setting up an empty password and giving local Kerberos some time to process it
${DSCL} . -passwd /Users/"${USERNAME}" ''
sleep 2
fi

if [[ ${OSVERS} -ge 7 ]]; then
${LOGGER} -s -t create"${USERNAME}".sh "INFO: Creating the "${USERNAME}" user account on Mac OS X 10.${OSVERS}.x"
${DSCL} . -create /Users/"${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_defaultLanguage de
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_guest true
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_writers__defaultLanguage "${USERNAME}"
# Adding the _writers_LinkedIdentity attribute for Macs running Mac OS X 10.7.x. This
# attribute is not needed on 10.8.x and later.
if [[ ${OSVERS} -eq 7 ]]; then
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_writers_LinkedIdentity "${USERNAME}"
fi
${DSCL} . -create /Users/"${USERNAME}" dsAttrTypeNative:_writers_UserCertificate "${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" AuthenticationHint ''
${DSCL} . -create /Users/"${USERNAME}" NFSHomeDirectory /Users/"${USERNAME}"
#setting up an empty password and giving local Kerberos some time to process it
${DSCL} . -passwd /Users/"${USERNAME}" "${USERNAME}"
sleep 2
${DSCL} . -create /Users/"${USERNAME}" Picture "/Library/User Pictures/Nature/Leaf.tif"
${DSCL} . -create /Users/"${USERNAME}" PrimaryGroupID "${GUESTGROUPID}"
${DSCL} . -create /Users/"${USERNAME}" RealName "${DISPLAYNAME}"
${DSCL} . -create /Users/"${USERNAME}" RecordName "${USERNAME}"
${DSCL} . -create /Users/"${USERNAME}" UniqueID "${GUESTUID}"
${DSCL} . -create /Users/"${USERNAME}" UserShell /bin/bash
#Adding the keychain item that allows "${USERNAME}" to login in 10.7 and later.
${SECURITY} add-generic-password -a "${USERNAME}" -s com.apple.loginwindow.guest-account -A -w "${USERNAME}" -D "application password" /Library/Keychains/System.keychain


# Restart loginwindow
/usr/bin/killall loginwindow
fi

${LOGGER} -s -t create"${USERNAME}".sh "INFO: Exiting"

exit 0