Synchronizing directory with Windows server

remodb
New Contributor II

I've been using a bash script run daily by a JSS policy to mount a Windows server share, synchronize its contents locally on every machine and then unmount the share. This has worked until Lion came along. It seems that 'mount_smbfs' won't authenticate properly when run as root. Here is the stripped down script with comments and error checking removed:

CLIENTPATH=/Users/Shared/Test
SERVERURL='//DOMAIN;botuser:password@server.designory.com/Test'
SERVERMOUNT=/Volumes/Test
SERVERPATH="/"
mkdir "$SERVERMOUNT"
/sbin/mount_smbfs -o nobrowse $SERVERURL "$SERVERMOUNT"
/usr/bin/rsync -aEu --exclude ".DS_Store" --exclude "Thumbs.db" --exclude ".T*" "$SERVERMOUNT$SERVERPATH" "$CLIENTPATH" --delete-after
chmod -R u=rwX,go=rX "$CLIENTPATH"
diskutil unmount "$SERVERMOUNT"

This works just fine when run as any user other than root.

Anyone else mounting SMB shares via a script that has found a workaround for this? Any suggestions on an alternate method to accomplish this task?

Thanks for any help.

1 ACCEPTED SOLUTION

remodb
New Contributor II

Ok, I think I've got a fair workaround for this issue. I opted to make a user-level LaunchAgent that triggers the script at a set time. Here are the LaunchAgent and script:

<?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>com.designory.sync_files</string>
    <key>LowPriorityIO</key>
    <true/>
    <key>Program</key>
        <string>/usr/local/bin/sync_files.sh</string>
    <key>ProgramArguments</key>
    <array>
        <string>sync_files.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>9</integer>
        <key>Minute</key>
        <integer>32</integer>
    </dict>
</dict>
</plist>
#!/bin/bash
CLIENTPATH=/Users/Shared/Test
SERVERURL='//DOMAIN;botuser:password@server.designory.com/Test'
SERVERMOUNT=/Volumes/Test
SERVERPATH="/"
mkdir "$SERVERMOUNT"
mount -t smbfs $SERVERURL "$SERVERMOUNT"
/usr/bin/rsync -aEu --exclude ".DS_Store" --exclude "Thumbs.db" "$SERVERMOUNT$SERVERPATH" "$CLIENTPATH" --delete-after
chmod -R ugo=rX "$CLIENTPATH"
diskutil unmount "$SERVERMOUNT"

The package fills the user template and existing user homes by placing the LaunchAgent at '~/Library/LaunchAgents' and the script in '/usr/local/bin'. On the next login, the LaunchAgent loads and can do its business from there.

I suppose I can write another script to run at the time the policy installs the package to test for a logged in user and use launchctl to load the LaunchAgent immediately, but I'm running thin on patience for this project. I'm also not thrilled that the script contains credentials and is accessible to the user if they dig, but the credentials are exclusive to this task, so it's not the end of the world.

I hope this helps someone else.

View solution in original post

2 REPLIES 2

mm2270
Legendary Contributor III

We've have a similar setup and had scripts in place that worked great when our Mac servers were running 10.6.8 Server. Now that we moved them up to Lion server, we've run into the same issue. mount_smbfs is broken under Lion for some odd reason. I attempted to find a valid workaround for it and the only thing I could come up with was to use an osascript to mount the server with an Applescript syntax in it. I don't like doing it this way for a number of reasons, but it does work, provided the servers that are mounting the Windows share are actually logged in to an account, like the local admin. It won't work if sitting at the login screen, since osascript expects the WindowServer.

So, something like this is what I have in the script:

SHARE_USR="shortname"
SHARE_PASS="password"

osascript -e 'open location "smb://" & SHARE_USR & ":" & SHARE_PASS & "@servername/path/to/SHARE/"' -e 'delay 5' -e 'tell application "Finder" to close window 1'

The only thing that sometimes doesn't work is the window closing function, usually because it times out if the share doesn't come up within 5 seconds. I could lengthen that, but I haven't bothered since the open window disappears later when the share is unmounted anyway. That part doesn't even really need to be there, but it bugs me how the Finder will pop open a window when a share is mounted that way.

I would love to find a way to go back to using our previous mount_smbfs command, but I get the feeling its going to take some 'give a damn' from Apple for them to actually fix this in Lion, and sadly, I don't think they give a damn frankly.

remodb
New Contributor II

Ok, I think I've got a fair workaround for this issue. I opted to make a user-level LaunchAgent that triggers the script at a set time. Here are the LaunchAgent and script:

<?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>com.designory.sync_files</string>
    <key>LowPriorityIO</key>
    <true/>
    <key>Program</key>
        <string>/usr/local/bin/sync_files.sh</string>
    <key>ProgramArguments</key>
    <array>
        <string>sync_files.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>9</integer>
        <key>Minute</key>
        <integer>32</integer>
    </dict>
</dict>
</plist>
#!/bin/bash
CLIENTPATH=/Users/Shared/Test
SERVERURL='//DOMAIN;botuser:password@server.designory.com/Test'
SERVERMOUNT=/Volumes/Test
SERVERPATH="/"
mkdir "$SERVERMOUNT"
mount -t smbfs $SERVERURL "$SERVERMOUNT"
/usr/bin/rsync -aEu --exclude ".DS_Store" --exclude "Thumbs.db" "$SERVERMOUNT$SERVERPATH" "$CLIENTPATH" --delete-after
chmod -R ugo=rX "$CLIENTPATH"
diskutil unmount "$SERVERMOUNT"

The package fills the user template and existing user homes by placing the LaunchAgent at '~/Library/LaunchAgents' and the script in '/usr/local/bin'. On the next login, the LaunchAgent loads and can do its business from there.

I suppose I can write another script to run at the time the policy installs the package to test for a logged in user and use launchctl to load the LaunchAgent immediately, but I'm running thin on patience for this project. I'm also not thrilled that the script contains credentials and is accessible to the user if they dig, but the credentials are exclusive to this task, so it's not the end of the world.

I hope this helps someone else.