Blog
Map “Network Drives” on Mac OS X Part 1.
Updated: 6/6/2007 I added some Apple script for all you Googlers.
First a little background: for a while now I have been teaching about “URL Fun” in my server classes. Its a pretty universal concept that you find server admins implementing on Mac OS X clients: the idea of an alias, link, script or application that connects to a server on login. The windows folks normally refer to this conceptually as a “Mapped Network Drive” which is why I choose it for the name of this article. I actually find it humorous how often I get asked to make a link to the “x” or “q” drive when doing consulting, its actually a testment to how simple this works on windows, people have no idea of the shares name, just the drive letter ( for better or worse sometimes ). Now there are multiple ways of accomplishing this on OS X ,some are better or fancier then others. All of them try at best to get around requiring users to use “Go” > “Connect To Server”
Part 1: “Aliases” and “Location” Files
Part 2: AppleScript and Login items
Part 3: Shell Scripts and Login Hooks
Part 4: Automounts with Directory Services
Lets take a look at some of the more basic “Alias” implementations
The most common and recommend method I see in the field is by dragging a drive’s icon ,mounted on the Desktop ( or /Volumes ) to the “System Preferences” > “Accounts” > “Login Items” for the respective user account. Whats going on behind the scenes is that the alias “data” that would normally exist in the resource fork of the filesystem has been inserted in to the “AliasData” key nested within the “AutoLaunchedApplicationDictionary” array of your users ~/Library/Preferences/loginwindow.plist file. There is actually one of these stored in the local /Library as well but we will cover that in part 2. You can view this “data” by runnning the following command ( type it in as you see it i.e. line break aka the “return” key is escaped by the “\” or get rid of the “\” and type it on one line.) Also some of the code in this article can be dowloaded by clicking on it.defaults read ~/Library/Preferences/loginwindow \AutoLaunchedApplicationDictionaryIn the output you will see the encoded alias data which is, if you make aliases this way in the finder you can view similar data or the resource fork in the file system using the “special” path “foobar/..namedfork/rsrc” ( “foobar/rsrc” works as well but its deprecated) I find this data easiest to look at with “less” or “strings” but its mostly meaningless to us humans.less -f /path/to/myalias/..namedfork/rsrc ; resetor to just see the ASCII stringsstrings /path/to/myalias/..namedfork/rsrcor if you have the developer tools installed you can use DeRez/Developer/Tools/DeRez /path/to/myalias This is normally the point where I ask people how many times they have seen a broken alias. Before you answer, I don’t want to chase any red hearings, aliases are not broken when you see the following behavior ( pictured below ) in your login items preferences pane.

This happens because the system can’t load the icon ( and kind ) when the volume is unmounted. So when the server volume is unmounted you will see the bottom example always. Because of this login aliases are very hard to troubleshoot as their content is encoded and they look the same when they are broken as they do when the are working (and unmounted). Feature or bug i’ll let you be the judge.

There are alot of reasons a “break” can happen but often the most common is in fact the simplest. When you created this alias data, quite a bit of infomation relating to how you orginally connected to the server is stored. Especially if you used the Network Browser then it was based around whatever broadcast protocol was being used to propagate the list at that moment, or if you used the “Go” > “Connect to Server” ( Command + K ) in the Finder there where multiple ways it could be resolving the address of our server in the alias.such as the following( For fun I have added code snippets if you dont know your server’s value )

The Bonjour (Rendevous) Name:
o
sudo /usr/sbin/systemsetup -getlocalsubnetname add .local to the end and this is your mDNS aka your Bonjour name Graphically “System Preferences” > “Sharing” > “Edit” Button (shown below )
The Fully Qualified Domain Name of your server:
o
/bin/hostname # shows the primary hostname only /usr/bin/host 10.1.0.1 /usr/bin/host 206.163.40.59 You could have many other hostnames and in fact we are looking up the “reverse”(PTR) record, but hopefully that will map back to a “forward”(A) record. The IP address (internal, external, multi-homed, etc.):
o
/sbin/ifconfig | /usr/bin/grep inet
systemsetup and networksetup do exist on client, they are just in a different place : /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Support/This basically means how you orginally connected to the server is how the alias will attempt to connect for then on in. If your servers values never changes this is still a good practice right? Well unfortunately not always no, on top of your servers connection address you might also be injecting a default user name (i.e. the username of the authenticated user who orginally connected to the share that the alias was created from). I for instance saw this at a school district , every local “student” account would open the server connection using the orginal admin’s username (who had created the NetRestore image) already filled in. Bit of hinderance having to blank it out and fill your username wouldnt you say? You actually can control this behavior using a preference key outline in this . Its also worthy of note that a proper kerberos setup should prevent this behavior, as you will only be allowed to auth as the Kerberos user in the case of at least AFPBefore we go through how not to do that lets quickly look at a scenario where you might in fact want to embed say “guest access” credentials in the alias. If when originally connecting we use Go Connect To Server, most of this information will be based on the URL we use to connect to the server.for SMS/CIFS URI’s this is normally just “guest@”: smb://guest@server.example.com For AFP Guest access its a little bit different idea as you can (in 10-10.4 at least) have a user actually named “guest”, so guest@ wont work,so there is a special string for this commonly found in the mount records (mentioned in later sections of this article) you can use. afp://;AUTH=NO%20USER%20AUTHENT@server.example.com you can in fact embed a password in using this method for many protocols such as AFP, SMB, and FTP (even SFTP by way of Transmit.app and other 3 party apps ), Perhaps you have a generic login for “guest” type access (not the you would ever do that right
) . afp://genericlogin:password@server.example.com/Share smb://DOMAIN;user:pass@server.example.com/SHARE Obviously this is not a secure practice unless you know exactly what your doing but as you can see you can make your aliases with more specific information using this method.Now while this would solve some issues in a small environment but it doesn’t scale well, imagine having to do this for all users in a large network.
Internet Location Files: A good first step and a “Classic” trick
- Even if you connect omitting the user@ field the alias will still embed it in its connection data,so as an alternative method we can use Internet Location Files. these come in many variations.Creating them is also pretty easy once you learn how. And they have been around along time too and thus are very compatible.
Type in the URL in to a new TextEdit.app Document
If you use spaces in your servers share names (shame on you ) remember to substitute those with “%20″ i.e. afp://server/My%20Spaced%20Share%20Name
Highlight the text
(if your like me and double click it to highlight, make sure to click once more at the next step. )
Click and hold on top on the highlighted text until your cursor changes to an “Arrow”
Now drag it out on to your Desktop.
I have found people sometimes have problems with this so read below for a non drag ‘n drop way using “Go” -> “Connect to Server”
Depending on the type of URL you typed in you will have created one of the following Location files and corresponding URLs.
foobar.fileloc a file system URL file://
foobar.afploc an AFP server URL file afp://
foobar.inetloc a Server Message Block (CIFS) URL
foobar.webloc a HTTP URL, (not WEBDAV)
foobar.ftploc a FTP URL (Finder is read only from the UI) There are others as well, but for our purposes this is what we probably want to mount
You can also even make them directly from a website’s links depending on your browser, here is one for –> Applications <– that uses the file:// URL type If you drag it (the word “Applications”) out onto your Desktop you will see a file created called “Application.fileloc”, and yes I know you cant click on it from within the browser ( as you might have noticed from my others above and through the rest of this article ) , but you can also drag it to the location bar making it almost as easy to launch.if you dont see the file extention (which is the default) you can enable file extentions from the Finder.app’s “Finder” menu (next to the Apple) under “Preferences” > “Advanced” > “Show all file extentions”. or use, defaults write -g AppleShowAllExtensions -bool YES Then if your finder is free to be killed ( i.e. not coping important CEO files ) you can use the following to apply the change killall -HUP Finder You should be able to double click on it and viola there is your Application folder. As a cool note many email clients like Mail.app and Entourage with parse these such links natively ( unlike your browser in the case of file://) making it a cinch to tell your users about a hard to find path like file:///System/Library/CoreServices/Kerberos.app You can also customise what application handles these URLs with RCDefaultApp a graphical LaunchServices Preference Pane.

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple Computer//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=”1.0″>
<dict>
<key>URL</key>
<string>afp://afp.example.com</string>
</dict>
</plist>
These files are infact the same type that are created by adding a favorite in the “Go” -> “Connect to Server” dialog box (the little plus sign), they are then stored in ~/Library/Favorites folder. The only exception is the “Server Address: ” box itself which can be configured with the following command.defaults write ~/Library/Preferences/com.apple.finder \FXConnectToLastURL 'afp://files.example.com/data'
You can in fact add your own items to this menu by way of making these location files and adding them to the folder ( They are greyed out but they work ). If you don’t specify a user@ then they will default to using the console users “RealName” sometime’s referred to as the “Long Name”. If that doesn’t suite your environment you can put bogus info in here like afp://FILLINYOURUSERNAME@server.example.com/Public To see or script the RealName value for a local user you can use dscl like this: dscl . -read /users/$USER RealName For a network LDAP user you can use:dscl /LDAPv3/iduro.wallcity.lan -read /Users/$USER RealName Or for an Active Directory user: dscl /Active\ Directory/All\ Domains/ -read /Users/$USER RealName
Now that we have files that we can embed specific connection data into, but how do we deploy them? Well as you might guess these can the be added as login items, the only problem is that they will not be embeded in the preference file like they alias data was, they instead will path names to the “flat” file locations. I like to add them to the login items and keep the orginating items in ~/Library/Favorites .The only real problem I have with this is that fact if the user deletes the orginal file , the login item reference is broken. One easy way to stop that from happening is to “lock” the favorites so that they cant easily be deleted through “Go”->”Connect to Server”, You can do the from the command line for all favorites:
chflags uchg ~/Library/Favorites/* or to reverse (unlock) the flag you can use “no”, also you can replace the star with a file name if you want to only effect a particular file in the folder. chflags nouchg ~/Library/Favorites/* This will affect only the current set , so users can add remove additional items. You can turn this flag on and off from the finder as well from the File>Get Info ( Command + I ) window.

If you dont want to deal with “locking” then another trick is to hide these files from your users by placing them in a “dot” folder
mkdir ~/Documents/.LoginItems mv ~/Desktop/my.afploc ~/Documents/.LoginItems/ open ~/Documents/.LoginItems only use “mv” in 10.4 or later as older styles of these files had important resource fork’s and older versions of mv did not move them. You can just drag and drop in the finder if you like.That last “open” bit is to open the “hidden” folder in the finder . This will prevent all but the savy from easily deleting these items most days. You could just as easily use “Go” -> “To Folder” or from the keyboard: “Command + Shift + G” and drag and drop.You could also put them into a folder in the “local domain” such as the local /Library/Application Support/.
If you use ARD you can automate this process with an Apple Script. Here is a pretty basic Apple Script that has been wrapped in whats known as a “here” document then executed by osascript
osascript << EOF tell application "System Events" make new login item at end of login items with properties {path:"/Library/Application Support/Irisink/Foobar.afploc"} end tell EOF Note: the user has to be logged in for this to work
The only real downside of the files that we have not covered is that they won’t always allow work due to the Network not being active at time of login ( Think Wireless, Spanning Tree etc ),So in our next section of this article we will turn our 6 line Apple Script into a 60 line version with pretty dialog boxes, fault tolerance and an artificial delay.So stay tuned for Part 2 of this series:AppleScript and Login items
Here is a quick taste of how to make an Applescript Login Item to mount multiple drives at the same time, and put in an artificial delay so we don’t timeout.First open up the /Applications/Applescript/Script Editor.app Add the following two lines: Click the code to open it up in Script Editor delay 5 -- I like to put a 5-10 second delay in mount volume "smb://user@allthestuffabove.com/Share"
You can continure to add mount volume lines,for any shares using the conventions above. mount volume "afp://user@allthestuffabove.com/Public" Those of you using ADmitMac may want to instead use the open location syntax: open location "cifs://DOMAIN;user@allthestuffabove.com/Public" When you are done, run your script to make sure it delays and then connects to all the share points listed. Once you have verfied it will workChoose File -> Save Asand choose “Application Bundle” from the “File Format:” Pop-Up

defaults write /path/to/Login.app/Contents/Info LSUIElement "1"If you would like to be able to use these applications in environments where you are using MCX or parental controls you must also specify a unique identifier.
defaults write /path/to/Login.app/Contents/Info CFBundleIdentifier "org.wallcity.myloginapp" beware the line break and insert a space
If would you like to contact me with comments or inaccuracies about this article, feel free but support requests will be ignored unless you would like to sign up for Iris Professional Services service. Thanks
Posted in Mac OS X Server, System Administration, Tips and Tricks
