Posted on
02-01-2016
05:24 PM
- last edited
a week ago
by
kh-richa_mig
We are in the process of moving away from OSX server and network homes. I have the os profiles mostly set for testing and now I am on to share. Our needs are as followed but I seem to be at a dead end with this.The machines are bound to AD and when logged in the root of the share drive is mounted:
1) I need the mounted share to be presented to the end user with their share, and not the entire share (even though presently they do not have permission to any other folders in the share but their own).From my understanding (which could be wrong) is that this is how Ad handles this by default.
2) I want my users Desktop, Documents, and Download folders redirected or symlinked to their smb share.
Any guidance or insights into this would be greatly appriciated
Thanks!
Posted on 02-02-2016 05:32 AM
What is Apple Enterprise Connect?
Enterprise Connect is an application that enhances Active Directory integration for OS X systems.
It performs three basic functions:
Kerberos
Enterprise Connect acquires a Kerberos Ticket Granting Ticket (TGT) when it detects your
organization’s network and automatically refreshes it as needed. A Kerberos TGT is useful for
organizations that use Kerberos authentication for resources like web sites or network share
points.
Account Management
Enterprise Connect uses Notification Center to notify a user when their Active Directory
password is nearing expiration. To change their password, a user simply clicks the notification to
change their Active Directory password within Enterprise Connect.
Network Share Management
Enterprise Connect can mount an Active Directory network home directory as well as SMB/AFP
shares defined by the user or administrator. Additionally, if these shares are disconnected, the
shares will be automatically re-mounted when the organizational network comes back online.
Requirements
Enterprise Connect requires the following:
■ OS X Mavericks (10.9) or later
■ An Active Directory domain
■ Connectivity to the network hosting the Active Directory domain
■ An Active Directory account
Enterprise Connect does not require being bound to Active Directory or that the user log into
their Mac with an Active Directory account. Additionally, no server side components are needed.
How does it work?
Enterprise Connect is simply an application. To set it up, the user launches it, enters their Active
Directory credentials and the hostname of their domain, then clicks Sign In. Once this is
complete, Enterprise Connect resides in the user’s menu bar.
When the organizational network is is detected, Enterprise Connect refreshes the user’s Kerberos
TGT, checks their password expiration status and re-mounts any shares that have become
disconnected. From this point onward, the user only needs to interact with Enterprise Connect if
they need to change their Active Directory password or configure the application
Contact Apple Professional Service about Enterprise Connect
Posted on 02-02-2016 05:54 AM
I appreciate the response
I must say this looks interesting, and i have reached out to our apple sales rep, but we are cutting out all OSX hardware on the backend. OSX is only going to be used for end points. If i am not making sense here please let me know
Thanks again!
Posted on 02-02-2016 06:07 AM
This sounds great! Forgive me if this is a dumb question, but how do you set up the client logins? Just have them all auto-login as a local guest-style account?
Posted on 02-02-2016 06:07 AM
Enterprise Connect doesn't require any Apple hardware on the backend. Just OS X clients, which you obviously already have. It's software that can be deployed to all your Mac clients that facilitates communication to AD, helps with share mounts, password expiration notices and so on. I would say it's something you should at least look into. It may be something that can help. It's not cheap, but it's a one time cost to purchase. The amount is primarily for professional on site services from Apple to help get it set up as I understand it.
Posted on 02-02-2016 06:29 AM
We are thinking of creating local Standard accounts on our Mac's and no longer have them bind to AD. EC will take care of letting staff update their AD password within EC and also we can push configuration profile to EC using JAMF if users need new network shares mounted.
Posted on 02-02-2016 06:34 AM
recommend everyone to take a look at Accellion Kiteworks as well. The latest release lets you create a secure container on workstation which is going to allow us to stop mouting network shares. They also release a new iOS app that will let your use with MS Office Apps to open internal network resources within the MS App.
The Accellion product is also a MDM, but only for the Kiteworks app and does not require the devices to be connected to VPN to access your internal resources.
Posted on 02-02-2016 11:41 AM
Apparently, this is in a pilot phase for education right now and there will be more information released at the end of the month.
Posted on 02-02-2016 12:27 PM
Our rep invited me to a webinar this week, but also said that for k-12 it hasn't been used. And he felt it to be overkill for what we are looking to do. He suggested ABE on the share to help hide all but their "homefolder" on the share. I would be fine with that just as long as we can create that symlink, or at least synced the contents of the folders back to their share without the student needing to interact with it. I realize if it is a moderately sized file and potentially 500+ kids are syncing it might be a long logout process so this would obviously be a concern. Using crashplan pro is not a options due to cost and bandwidth restraints. Given that this is a shared environment the student experience is the sticking point with the redirect issue. Teacher machine (until we can refresh to macbook air) should not be that big of an issue as they all have dedicated machines in their rooms and they can be trained to look at the share drive when not at their machine.
Any thoughts are greatly appreciated and welcomed
Posted on 02-03-2016 08:19 AM
I have been looking at moving from "network homes" to "forced local homes" myself at some point, and when I do, I also require certain folders to be redirected to their network equivalents. So I knocked this script together.
The script sets itself up as a LaunchAgent that runs when the Finder loads.
It finds the user network home, and creates the links.
You should note that the script assumes that by the time you get to the Finder, the network home is mounted.
I hope it is of some use to you
If there is an easier way to do this, I apologise in advance.
#!/bin/bash
# RedirForcedLocalHomes
# Create folder redirections for network accounts with forced local homes
# Version 1.0.1
# Mark J Swift
#
# To customise:
# look for BEGIN CUSTOMISE in the script
#
# To test:
# log in as a user, and run the script from a Terminal
#
# To install as a post-login LaunchAgent:
# log in as an admin and type the following in a terminal:
# sudo ThisScriptName
#
# Installs into /usr/local/yourdomain/scripts/ and /Library/LaunchAgents/
# -- Get some info about this script
# Get filename of this script
GLB_ThisScriptName="$(basename "${0}")"
# -- Get some info about the workstation
# Get full domain name
AD_DOMAINNAME_DNS=$(echo "show com.apple.opendirectoryd.ActiveDirectory" | scutil | grep "DomainNameDns" | cut -d":" -f 2- | sed "s|^[ ]*||;s|[ ]*$||")
# Initial error check
if test -z "${AD_DOMAINNAME_DNS}"
then
echo >&2 "Workstation doesn't appear to be part of a domain"
exit 0
fi
# -- Get some info about the user
# Get user name
GLB_UserName="$(whoami)"
# Get user ID
GLB_UserID="$(id -u ${GLB_UserName})"
# Check if user is a local account (returns "yes" or "no")
GLB_IsLocalAccount=$(dseditgroup -o checkmember -m "${GLB_UserName}" -n . localaccounts | cut -d" " -f1)
# -- Check if we are actually installing the script
if [ "${GLB_UserName}" = "root" ]
then
# Build a name for the LaunchAgent Plist file
GLB_LaunchAgentName="$(echo "${AD_DOMAINNAME_DNS}" | tr "." "
" | tail -r | tr "
" "." | sed "s|.$||")"".""${GLB_ThisScriptName}"
# Path that holds this organisations custom installations
GLB_CustomInstallPath="/usr/local/${AD_DOMAINNAME_DNS}"
# Copy this script to this organisations script folder
mkdir -p "${GLB_CustomInstallPath}/scripts"
cp -f "${0}" "${GLB_CustomInstallPath}/scripts/"
# Set permissions
chown -R root:wheel "${GLB_CustomInstallPath}"
chmod -R 755 "${GLB_CustomInstallPath}"
# Create LaunchAgent plist
cat << HEREDOC > "/Library/LaunchAgents/${GLB_LaunchAgentName}.plist"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>${GLB_LaunchAgentName}</string>
<key>ProgramArguments</key>
<array>
<string>${GLB_CustomInstallPath}/scripts/${GLB_ThisScriptName}</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>LimitLoadToSessionType</key>
<string>Aqua</string>
</dict>
</plist>
HEREDOC
# Set permissions on LaunchAgent plist
chown root:wheel "/library/LaunchAgents/${GLB_LaunchAgentName}.plist"
chmod 644 "/library/LaunchAgents/${GLB_LaunchAgentName}.plist"
echo >&2 "Installed LaunchAgent ${GLB_LaunchAgentName}.plist"
echo >&2 "Now you need to restart the workstation..."
exit 0
fi
# If we got here, we are running the script - not installing it
# -- Define some functions
f_UndoFolderRedir() # FileRedirectList TargetHomeDir - Undo any existing home folder redirections
{
local LCL_TargetHomeDir
local LCL_FileRedirectList
local LCL_ReqdLinkEntry
local LCL_ReqdLinkFile
LCL_FileRedirectList="${1}"
LCL_TargetHomeDir="${2}"
if test -f "${LCL_FileRedirectList}"
then
# We may have symbolic links that need to be removed
while read LCL_ReqdLinkEntry
do
# Sanitise the Entry
LCL_ReqdLinkEntry=$(echo "/${LCL_ReqdLinkEntry}" | sed "s|/[/]*|/|g")
LCL_ReqdLinkFile=$(echo "${LCL_ReqdLinkEntry}" | sed "s|/$||")
if test -n "${LCL_ReqdLinkFile}"
then
if test -L "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
then
# There is a symbolic link where our file/folder should be
if [ "${LCL_ReqdLinkEntry}" != "${LCL_ReqdLinkFile}" ]
then
# If the link was on a directory, re-create directory
/bin/rm -f "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
mkdir -p "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
else
/bin/rm -f "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
fi
fi
fi
done < "${LCL_FileRedirectList}"
fi
}
f_DoFolderRedir() # FileRedirectList TargetHomeDir SourceHomeDir
{
local LCL_TargetHomeDir
local LCL_SourceHomeDir
local LCL_FileRedirectList
local LCL_BackupDir
local LCL_ReqdLinkEntry
local LCL_ReqdLinkFile
local LCL_EnclosingDir
local LCL_TargetIsLocal
local LCL_StartEpoch
LCL_FileRedirectList="${1}"
LCL_TargetHomeDir="${2}" # Where the link files will be created
LCL_SourceHomeDir="${3}" # Where the files/folders are that the links will be pointing to to
# Take a note when this function started
LCL_StartEpoch=$(date -u "+%s")
if test -f "${LCL_FileRedirectList}"
then
# Decide whether the target is on the local drive
if test -n "$(stat -f "%Sd" "${LCL_TargetHomeDir}" | grep "^disk")"
then
LCL_TargetIsLocal="yes"
else
LCL_TargetIsLocal="no"
fi
# Backup location for existing files/folders that might be replaced by a link
LCL_BackupDir="${LCL_TargetHomeDir}/Backup/"$(date -r ${LCL_StartEpoch} '+%Y-%m-%d_%H-%M-%S')
# Read entries from file
while read LCL_ReqdLinkEntry
do
# Sanitise the Entry
LCL_ReqdLinkEntry=$(echo "/${LCL_ReqdLinkEntry}" | sed "s|/[/]*|/|g")
LCL_ReqdLinkFile=$(echo "${LCL_ReqdLinkEntry}" | sed "s|/$||")
if test -n "${LCL_ReqdLinkFile}"
then
if test -e "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
then
if test -d "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
then
# If the existing folder at the target is local, remove any ACLs that might stop us doing our stuff
if [ "${LCL_TargetIsLocal}" = "yes" ]
then
/bin/chmod -RN "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
fi
# Check if existing folder is empty - and backup if necessary
if test -z "$(ls -A1 "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}" | grep -Ev "^.DS_Store$|^.localized$")"
then
/bin/rm -fR "${LCL_TargetHomeDir}/${LCL_ReqdLinkFile}"
else
# Make sure there is a target enclosing folder to backup the folder
LCL_EnclosingDir="$(dirname "${LCL_BackupDir}${LCL_ReqdLinkFile}")"
/bin/mkdir -p "${LCL_EnclosingDir}"
# Move (back up) existing folder at target
/bin/mv -f "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}" "${LCL_EnclosingDir}/"
fi
else
# If the existing file at the target is local, remove any ACLs that might stop us doing our stuff
if [ "${LCL_TargetIsLocal}" = "yes" ]
then
/bin/chmod -N "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
fi
# Make sure there is a target enclosing folder to backup the file
LCL_EnclosingDir="$(dirname "${LCL_BackupDir}${LCL_ReqdLinkFile}")"
/bin/mkdir -p "${LCL_EnclosingDir}"
# Move (back up) existing file at target
/bin/mv -f "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}" "${LCL_EnclosingDir}/"
fi
fi
# Make sure there is a target enclosing folder to store the symbolic link
LCL_EnclosingDir="$(dirname "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}")"
/bin/mkdir -p "${LCL_EnclosingDir}"
# Make sure we have a source folder or source file parent folder
if [ "${LCL_ReqdLinkEntry}" != "${LCL_ReqdLinkFile}" ]
then
# We are linking to a directory - so make sure it exists
/bin/mkdir -p "${LCL_SourceHomeDir}${LCL_ReqdLinkFile}"
else
# We are linking to a file - so make sure the parent folder exists
LCL_EnclosingDir="$(dirname "${LCL_SourceHomeDir}${LCL_ReqdLinkFile}")"
/bin/mkdir -p "${LCL_EnclosingDir}"
fi
# Create link - source file/folder -to- target link
/bin/ln -sf "${LCL_SourceHomeDir}${LCL_ReqdLinkFile}" "${LCL_TargetHomeDir}${LCL_ReqdLinkFile}"
fi
done < "${LCL_FileRedirectList}"
fi
}
# urldecode function - thanks to https://gist.github.com/cdown/1163649
f_urldecode() {
# urldecode <string>
local url_encoded="${1//+/ }"
printf '%b' "${url_encoded//%/\x}"
}
# -- Get the user home properties
# Get the User Home directory
GLB_UserHomeDir=$(eval echo ~${GLB_UserName})
# Decide whether the user home is on the local drive
if test -n "$(stat -f "%Sd" "${GLB_UserHomeDir}" | grep "^disk")"
then
GLB_IsLocalHome="yes"
else
GLB_IsLocalHome="no"
fi
# Get the network defined home directory
if [ "${GLB_IsLocalAccount}" = "no" ]
then
# - Network user -
# Get UserHomeNetworkURI
# ie: smb://yourserver.com/staff/t/testuser
# or smb://yourserver.com/Data/Student%20Homes/Active_Q2/pal/teststudpal
GLB_UserHomeNetworkURI=$(dscl 2>/dev/null localhost -read /Search/Users/${GLB_UserName} HomeDirectory | sed "s|HomeDirectory: ||;s|<[^>]*>||g;s|/$||;s|^[^:]*:||")
if test -z "${GLB_UserHomeNetworkURI}"
then
GLB_UserHomeNetworkURI=$(dscl 2>/dev/null localhost -read /Search/Users/${GLB_UserName} OriginalHomeDirectory | sed "s|OriginalHomeDirectory: ||;s|<[^>]*>||g;s|/$||")
fi
if test -n "${GLB_UserHomeNetworkURI}"
then
# The user home directory has been forced from the network to a local drive
# Get full path to the network HomeDirectory
# ie: /Volumes/staff/t/testuser
# or /Volumes/Data/Student Homes/Active_Q2/pal/teststudpal
while read LCL_MountEntry
do
LCL_MountPoint=$(echo ${LCL_MountEntry} | sed -E 's|(^.*) on (.*) ((.*))|2|' | grep -v '^/$')
LCL_MountShare=$(echo ${LCL_MountEntry} | sed -E 's|(^.*) on (.*) ((.*))|1|' | sed 's|'${GLB_UserName}'@||')
if test -n "$(echo "${GLB_UserHomeNetworkURI}" | sed "s|^[^:]*:||" | grep -E "^${LCL_MountShare}")"
then
GLB_UserHomeNetworkDir=$(f_urldecode "${LCL_MountPoint}$(echo ${GLB_UserHomeNetworkURI} | sed "s|^[^:]*:||;s|^"${LCL_MountShare}"||")")
break
fi
done < <(mount | grep "//${GLB_UserName}@")
fi
fi
# -- Now do some error checking
if ! test -e "${GLB_UserHomeDir}"
then
echo >&2 "User home doesn't exist"
exit 0
fi
if [ "${GLB_IsLocalHome}" = "no" ]
then
echo >&2 "User home isn't on a local drive"
exit 0
fi
# -- Now we can do the file/folder linking
# Move any existing link list
touch "${GLB_UserHomeDir}/.FolderRedir.txt"
mv -f "${GLB_UserHomeDir}/.FolderRedir.txt" "${GLB_UserHomeDir}/.FolderRedir-Old.txt"
# Create a new empty link list
touch "${GLB_UserHomeDir}/.FolderRedir.txt"
# If a network home exists, populate the empty link list
if test -n "${GLB_UserHomeNetworkDir}"
then
# -- BEGIN CUSTOMISE --
cat << HEREDOC >> "${GLB_UserHomeDir}/.FolderRedir.txt"
/Desktop/
/Documents/
/Library/Group Containers/
/Movies/
/Music/
/Pictures/
HEREDOC
# -- END CUSTOMISE --
fi
# Find out which folders we need to check for links/unlinks
echo "$(cat "${GLB_UserHomeDir}/.FolderRedir.txt" ; cat "${GLB_UserHomeDir}/.FolderRedir-Old.txt" )" | sort -u > "${GLB_UserHomeDir}/.FolderRedir-Check.txt"
# Find out which folders we need to unlink (if we ever change the link list)
echo "$(cat "${GLB_UserHomeDir}/.FolderRedir.txt" ; cat "${GLB_UserHomeDir}/.FolderRedir-Check.txt" )" | sort | uniq -u > "${GLB_UserHomeDir}/.FolderRedir-Unlink.txt"
# Find out which folders we need to link
echo "$(cat "${GLB_UserHomeDir}/.FolderRedir-Old.txt" ; cat "${GLB_UserHomeDir}/.FolderRedir-Check.txt" )" | sort | uniq -u > "${GLB_UserHomeDir}/.FolderRedir-Link.txt"
# Link files
f_DoFolderRedir "${GLB_UserHomeDir}/.FolderRedir-Link.txt" "${GLB_UserHomeDir}" "${GLB_UserHomeNetworkDir}"
# Unlink files
f_UndoFolderRedir "${GLB_UserHomeDir}/.FolderRedir-Unlink.txt" "${GLB_UserHomeDir}"
# Check if the Desktop was linked/unlinked
if test -n "$(printf "$(cat "${GLB_UserHomeDir}/.FolderRedir-Unlink.txt";cat "${GLB_UserHomeDir}/.FolderRedir-Link.txt")" | grep -E "^/Desktop/$")"
then
# Kill the Finder (Refreshes Desktop)
pkill -U ${GLB_UserID} Finder
fi
# Delete temporary files
rm -f "${GLB_UserHomeDir}/.FolderRedir-Old.txt"
rm -f "${GLB_UserHomeDir}/.FolderRedir-Check.txt"
rm -f "${GLB_UserHomeDir}/.FolderRedir-Unlink.txt"
rm -f "${GLB_UserHomeDir}/.FolderRedir-Link.txt"
# Delete the link file if it is empty
if ! test -s "${GLB_UserHomeDir}/.FolderRedir.txt"
then
rm -f "${GLB_UserHomeDir}/.FolderRedir.txt"
fi
# ---
Redirecting local folders to point to network folders can be more of a chore than you may expect.
If you are not in control of your network shares, you can never be sure of how home directories will be mounted. You could be presented with the root of the share, or the root of the user home. This is uncertain until the user home is actually mounted.
Also, with "Force local home directory on startup disk" enabled, the user home is not actually mounted until after login.
For these reasons, the path to the network home is uncertain until immediately after login and shouldn't really be assumed to follow any sort of pattern.