Skip to content

Instantly share code, notes, and snippets.

@faun
Last active July 8, 2020 10:50
Show Gist options
  • Save faun/1c0ffb639b4ba419d07f to your computer and use it in GitHub Desktop.
Save faun/1c0ffb639b4ba419d07f to your computer and use it in GitHub Desktop.
Script to mount remote SMB volume using password stored in Mac OS keychain without needing admin or sudo priveliges
#!/usr/bin/env bash
# Fetch the password from the keychain if it exists
PASSWORD_ENTERED=false
ACCOUNT_NAME='login'
SERVICE_NAME='mount_volume'
PASSWORD=$(
security 2> /dev/null \
find-generic-password -w \
-a $ACCOUNT_NAME \
-s $SERVICE_NAME
)
# Stop the script from continuing if there's an error
set -e
# Remote file user
REMOTE_USER='video'
# Remote file server
REMOTE_SERVER='terraform.faun.me'
# Volumes to mount
declare -a REMOTE_MOUNTS=(Television Movies)
# Where to mount volumes
LOCAL_DESTINATION="$HOME/Mount/"
# Prompt for password if not in keychain
if [ -z $PASSWORD ]; then
echo "Enter the password for user ${REMOTE_USER} on ${REMOTE_SERVER}:"
read -s PASSWORD
PASSWORD_ENTERED=true
fi
# URL escape the password (allow for special characters in the password)
ENCODED_PASSWORD="$(
perl -MURI::Escape -e \
'print uri_escape($ARGV[0]);' \
"$PASSWORD"
)"
# Mount each volume from $REMOTE_MOUNTS to $LOCAL_DESTINATION
for MOUNT in ${REMOTE_MOUNTS[*]}
do
mkdir -p "$LOCAL_DESTINATION/$MOUNT"
mount_smbfs -o \
automounted \
-N "//${REMOTE_USER}:$ENCODED_PASSWORD@${REMOTE_SERVER}/${MOUNT}/" \
"$LOCAL_DESTINATION/$MOUNT"
done
# Save the password to the keychain if provided
if [ $PASSWORD_ENTERED != false ]
then
security add-generic-password \
-a $ACCOUNT_NAME \
-l "Volume mount password for user ${REMOTE_USER} on ${REMOTE_SERVER}" \
-s $SERVICE_NAME \
-w $PASSWORD
fi
@Brunnocampos1
Copy link

Brunnocampos1 commented Jan 25, 2018

Dear Mr. Faun,

First of all, thanks for your clean and smart code. This solves my problem in many directions.

I will explain a bit about a problem I am facing if you want to go directly to the point please go to the "Direct to the point" paragraph.

I am implementing a Database interface in my lab and I need to create this interface for Windows, Linux and OSx. All is working good but my central problem is that on OSx, the smb connection (to a windows machine where a database actually is) is frequently shut down by the OSx. The GUI I wrote has also an assistant to create the connection to the server and do this for two folders in the same Server Windows Machine. I am trying to use you Code in this Connection Assistant.

DIRECT TO THE POINT: I am using a bash code completely inspired by your (thanks again) to connect to 2 distinct folders in the same machine. I need to run the code twice, one for each folder, due to GUI reasons. The code works for the first folder, but not for the second. Both folders are accessible by OSx "Connection to the Server" interface
Code 1 (working):

#!/usr/bin/env bash

PASSWORD_ENTERED=true

ACCOUNT_NAME='DBlni'

SERVICE_NAME='mount_DB_volume'

PASSWORD='REALPASSORD' # here I add the real Server user password
REMOTE_USER='BD'

REMOTE_SERVER='143.BBB.CCC.ZZ/Users/BD/'  # 143.BBB.CCC.ZZ is IP adress of the server

security add-generic-password -a $ACCOUNT_NAME -l "Volume mount password for user ${REMOTE_USER} on ${REMOTE_SERVER}" -s $SERVICE_NAME -w $PASSWORD

PASSWORD=$(security 2> /dev/null find-generic-password -w -a $ACCOUNT_NAME -s $SERVICE_NAME)

declare -a REMOTE_MOUNTS=(DBlniAdd)

LOCAL_DESTINATION="/Users/bmc/Documents/DBlni_Find"

ENCODED_PASSWORD="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$PASSWORD")"

for MOUNT in ${REMOTE_MOUNTS[*]}
do
   mkdir -p "$LOCAL_DESTINATION/$MOUNT"
   mount_smbfs -o automounted -N "//${REMOTE_USER}:$ENCODED_PASSWORD@${REMOTE_SERVER}/${MOUNT}/" "$LOCAL_DESTINATION/$MOUNT"
done

This code works fine, the mount is completed, and the keychain added.

The second cone (NOT WORKING, ERROR: mount_smbfs: mount error: /Users/bmc/Documents/DBlni_Find/Repositorio: Unknown error: -1073741412)

#!/usr/bin/env bash

PASSWORD_ENTERED=true

ACCOUNT_NAME='Repository'

SERVICE_NAME='mount_RP_volume'

PASSWORD='REALPASSORD' # here I add the real Server user password

REMOTE_USER='BD'

REMOTE_SERVER='143.BBB.CCC.ZZ/'  # 143.BBB.CCC.ZZ is the IP address of the server

security add-generic-password -a $ACCOUNT_NAME -l "Volume mount password for user ${REMOTE_USER} on ${REMOTE_SERVER}" -s $SERVICE_NAME -w $PASSWORD

PASSWORD=$(security 2> /dev/null find-generic-password -w -a $ACCOUNT_NAME -s $SERVICE_NAME)

declare -a REMOTE_MOUNTS=(Repositorio) #this folder is on the root of a D:\ unit. (143.BBB.CCC.ZZ/Repositorio)

LOCAL_DESTINATION="/Users/bmc/Documents/DBlni_Find"

ENCODED_PASSWORD="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$PASSWORD")"

for MOUNT in ${REMOTE_MOUNTS[*]}
do
   mkdir -p "$LOCAL_DESTINATION/$MOUNT"
   mount_smbfs -o automounted -N "//${REMOTE_USER}:$ENCODED_PASSWORD@${REMOTE_SERVER}/${MOUNT}/" "$LOCAL_DESTINATION/$MOUNT"
done

As you noticed the codes are very similar, changing only the server folder
Thank you very much for any tip.

@Brunnocampos1
Copy link

Just Solved. The problem was a double '/' on the address. My bad. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment