Page 1 of 1

[Linux]Make SS ask for (linux) username and pass at start

PostPosted: Thu May 05, 2011 2:17 pm
by 3R3
I run SS on a headless server, so since I never reboot that machine I wanted a way to quickly start SS under different user credentials, and asking the pass before going through with it.

For this I modified the subsonic.sh from the standalone package. This is really just basic linux shell code I added, so its not really distribution or SS package related. If it has bash, it will work. Though it's not so practical to use the terminal-sudo in a gui startup situation or for autostart at boot.

So this was made with manual starting and stopping in mind, to potentially add multiple servers to a machine and/or test different user credentials for running SS, permissions etc.

Its also possible to set a fixed user in my version of subsonic.sh and just use the new --user=name parameter to override the default if need be.

Please note, if you dont set the user manually at the top of the script by assigning it to the variable SUBSONIC_USER, you NEED to provide it with the --user=username option. Else SS will fail to start (on purpose, unclear credentials situation). A password for the specified user will have to be entered either way though.

One final note:
Theres currently no error handling done when a user is entered that is not present on the system! Then, SS will _not_ start but it will also _not_ throw an error...Maybe someone can help me out here. This script really was made only for me as a quick fix, but if someone finds it handy thats good too :)

The "patch" is in noob-form, like this:
find:
Code: Select all
old text

replace with:
Code: Select all
new text
old text


!!!
PLEASE:
-STOP SERVER
-BACKUP SS FOLDER
-ONLY THEN EDIT FILES
-START SERVER WHEN FINISHED EDITING ONLY
!!!


In subsonic.sh in the SS main directory,
find:
Code: Select all
SUBSONIC_HOME=/var/subsonic

replace with:
Code: Select all
SUBSONIC_USER=
SUBSONIC_HOME=/var/subsonic


find:
Code: Select all
echo "  --home=DIR           The directory where Subsonic will create files."

replace with:
Code: Select all
echo "  --user=USERNAME      Specify the user under which SS shall be run."
echo "  --home=DIR           The directory where Subsonic will create files."



find:
Code: Select all
--home=?*)
            SUBSONIC_HOME=${1#--home=}
            ;;

replace with:
Code: Select all
--user=?*)
            SUBSONIC_USER=${1#--user=}
            ;;
--home=?*)
            SUBSONIC_HOME=${1#--home=}
            ;;



find:
Code: Select all
${JAVA} -Xmx${SUBSONIC_MAX_MEMORY}m \


replace with:
Code: Select all
# Test if username was given as Parameter, else exit with error
if [ -z $SUBSONIC_USER ]; then
    echo "ERROR: No username given!"
    echo "use parameter --user or set the username manually at the top of this script"
    echo
    usage
    exit 1;
fi

su $SUBSONIC_USER -c "${JAVA} -Xmx${SUBSONIC_MAX_MEMORY}m \
  -Dsubsonic.home=${SUBSONIC_HOME} \
  -Dsubsonic.host=${SUBSONIC_HOST} \
  -Dsubsonic.port=${SUBSONIC_PORT} \
  -Dsubsonic.contextPath=${SUBSONIC_CONTEXT_PATH} \
  -Dsubsonic.defaultMusicFolder=${SUBSONIC_DEFAULT_MUSIC_FOLDER} \
  -Dsubsonic.defaultPodcastFolder=${SUBSONIC_DEFAULT_PODCAST_FOLDER} \
  -Dsubsonic.defaultPlaylistFolder=${SUBSONIC_DEFAULT_PLAYLIST_FOLDER} \
  -Djava.awt.headless=true \
  -jar subsonic-booter-jar-with-dependencies.jar > ${LOG} 2>&1 &"


EDIT: Why would I want this? So I dont accidently start SS as root, which brings a host of problems with it. Not only is security severely compromised, also all uploaded files will be owned by root which is a bitch if you just want to tag/fix a huge bunch of files and somehow it doesnt work as exected ;-) Also, all files created by SS will be owned by root, which is not what I want.
Alternatively you can use this to conveniently start several instances of SS, each from a different user (eg. user private, user public or whatever) without getting too confused.

PostPosted: Tue May 24, 2011 9:55 am
by 3R3
I realized that it isnt very helpful to "patch" a shell script. so here is the ready-made, drop-in replacement for your subsonic.sh.
Although all you console users probably dont need this, maybe someone will find it helpful.

I updated it a bit, it now prints the user who starts SS and asks for the starting users password on standard out (ie. the console in most cases).

Code: Select all
#!/bin/sh

###################################################################################
# Shell script for starting Subsonic.  See http://subsonic.org.
#
# Author: Sindre Mehus
# (modified by 3R3)
###################################################################################

# set username manually below
#SUBSONIC_USER=yourusername
SUBSONIC_USER=
SUBSONIC_HOME=/var/subsonic
SUBSONIC_HOST=0.0.0.0
SUBSONIC_PORT=55555
SUBSONIC_CONTEXT_PATH=/
SUBSONIC_MAX_MEMORY=1024
SUBSONIC_PIDFILE=
SUBSONIC_DEFAULT_MUSIC_FOLDER=/path/to/music
SUBSONIC_DEFAULT_PODCAST_FOLDER=/path/to/podcasts
SUBSONIC_DEFAULT_PLAYLIST_FOLDER=/path/to/playlists

quiet=0

usage() {
    echo "Usage: subsonic.sh [options]"
    echo "  --help               This small usage guide."
    echo "  --user=USERNAME    Specify the user under which SS shall be run."
    echo "  --home=DIR           The directory where Subsonic will create files."
    echo "                       Make sure it is writable. Default: /var/subsonic"
    echo "  --host=HOST          The host name or IP address on which to bind Subsonic."
    echo "                       Only relevant if you have multiple network interfaces and want"
    echo "                       to make Subsonic available on only one of them. The default value"
    echo "                       will bind Subsonic to all available network interfaces. Default: 0.0.0.0"
    echo "  --port=PORT          The port on which Subsonic will listen for"
    echo "                       incoming HTTP traffic. Default: 4040"
    echo "  --context-path=PATH  The context path, i.e., the last part of the Subsonic"
    echo "                       URL. Typically '/' or '/subsonic'. Default '/'"
    echo "  --max-memory=MB      The memory limit (max Java heap size) in megabytes."
    echo "                       Default: 100"
    echo "  --pidfile=PIDFILE    Write PID to this file. Default not created."
    echo "  --quiet              Don't print anything to standard out. Default false."
    echo "  --default-music-folder=DIR    Configure Subsonic to use this folder for music.  This option "
    echo "                                only has effect the first time Subsonic is started. Default '/var/music'"
    echo "  --default-podcast-folder=DIR  Configure Subsonic to use this folder for Podcasts.  This option "
    echo "                                only has effect the first time Subsonic is started. Default '/var/music/Podcast'"
    echo "  --default-playlist-folder=DIR Configure Subsonic to use this folder for playlists.  This option "
    echo "                                only has effect the first time Subsonic is started. Default '/var/playlists'"
    exit 1
}

# Parse arguments.
while [ $# -ge 1 ]; do
    case $1 in
        --help)
            usage
            ;;
        --user=?*)
            SUBSONIC_USER=${1#--user=}
            ;;
        --home=?*)
            SUBSONIC_HOME=${1#--home=}
            ;;
        --host=?*)
            SUBSONIC_HOST=${1#--host=}
            ;;
        --port=?*)
            SUBSONIC_PORT=${1#--port=}
            ;;
        --context-path=?*)
            SUBSONIC_CONTEXT_PATH=${1#--context-path=}
            ;;
        --max-memory=?*)
            SUBSONIC_MAX_MEMORY=${1#--max-memory=}
            ;;
        --pidfile=?*)
            SUBSONIC_PIDFILE=${1#--pidfile=}
            ;;
        --quiet)
            quiet=1
            ;;
        --default-music-folder=?*)
            SUBSONIC_DEFAULT_MUSIC_FOLDER=${1#--default-music-folder=}
            ;;
        --default-podcast-folder=?*)
            SUBSONIC_DEFAULT_PODCAST_FOLDER=${1#--default-podcast-folder=}
            ;;
        --default-playlist-folder=?*)
            SUBSONIC_DEFAULT_PLAYLIST_FOLDER=${1#--default-playlist-folder=}
            ;;
        *)
            usage
            ;;
    esac
    shift
done

# Use JAVA_HOME if set, otherwise assume java is in the path.
JAVA=java
if [ -e "${JAVA_HOME}" ]
    then
    JAVA=${JAVA_HOME}/bin/java
fi

# Create Subsonic home directory.
mkdir -p ${SUBSONIC_HOME}
LOG=${SUBSONIC_HOME}/subsonic_sh.log
rm -f ${LOG}

cd $(dirname $0)
if [ -L $0 ] && ([ -e /bin/readlink ] || [ -e /usr/bin/readlink ]); then
    cd $(dirname $(readlink $0))
fi

# Test if username was given as Parameter or set in this script, else exit with error
if [ -z $SUBSONIC_USER ]; then
    echo "ERROR: No username given!"
    echo "use parameter --user=USERNAME or set the username manually at the top of this script"
    echo
    usage
    exit 1;
fi

# ask for users password
echo $SUBSONIC_USER please enter

su $SUBSONIC_USER -c "${JAVA} -Xmx${SUBSONIC_MAX_MEMORY}m \
  -Dsubsonic.home=${SUBSONIC_HOME} \
  -Dsubsonic.host=${SUBSONIC_HOST} \
  -Dsubsonic.port=${SUBSONIC_PORT} \
  -Dsubsonic.contextPath=${SUBSONIC_CONTEXT_PATH} \
  -Dsubsonic.defaultMusicFolder=${SUBSONIC_DEFAULT_MUSIC_FOLDER} \
  -Dsubsonic.defaultPodcastFolder=${SUBSONIC_DEFAULT_PODCAST_FOLDER} \
  -Dsubsonic.defaultPlaylistFolder=${SUBSONIC_DEFAULT_PLAYLIST_FOLDER} \
  -Djava.awt.headless=true \
  -jar subsonic-booter-jar-with-dependencies.jar > ${LOG} 2>&1 &"

# Write pid to pidfile if it is defined.
if [ $SUBSONIC_PIDFILE ]; then
    echo $! > ${SUBSONIC_PIDFILE}
fi

if [ $quiet = 0 ]; then
    echo Started Subsonic [PID $!, ${LOG}]
    echo as user $SUBSONIC_USER
fi