#!/bin/bash
# This script installs the FollowMe print queue at NTNU on Linux (and possibly Mac) systems.
# The targeted and tested distros are: Debian, Ubuntu (and derivates), Fedora, CentOS, OpenSUSE and Mint
-# Copyright © 2017 einar.haraldseid@ntnu.no
+# Copyright © 2017-2019 einar.haraldseid@ntnu.no
# Documentation
function usage {
echo " -m, --model {ricoh|generic} Printer model to install (default: generic)"
echo " -d, --driver {pcl,postscript} Printer driver to use (default: postscript)"
echo " -f, --force Force running script as if on Linux systems"
+ echo " -p, --plaintext Store credentials as plaintext in /etc/cups/printers.conf (Linux only)"
echo " -h, --help Display this help text"
}
# Set other default options
PrintServer="followprint.win.ntnu.no"
-QueueName="FollowMe"
+PrintFile="ntnuprint-ricoh"
Workgroup="WIN-NTNU-NO"
+QueueName="FollowMe"
while [[ $# -gt 0 ]]; do
Key="${1}"
printerror "Unknown driver ${Driver}, plase choose one of postscript or pcl"
exit 1
fi
- shift # Jump to next option
+ shift # Jump to next argument
+ ;;
+ -p|--plaintext)
+ Plaintext="YES"
+ shift # Jump to next argument
;;
-h|--help)
usage
exit 0
;;
*)
- # unknown option
- echo "Unknown option: ${Key}"
+ # Unknown argument
+ echo "Unknown argument: ${Key}"
exit 1
;;
esac
Uname="linux"
fi
-# Set printer share based on model (generic goes to ntnuprint-xerox)
-if [ "${Model}" = "ricoh" ]; then
- PrintShare="ntnuprint-ricoh"
-else
- PrintShare="ntnuprint-xerox"
-fi
-
# Set printer driver path based on driver (we will override these if we're specific distros
if [ "${Driver}" = "postscript" ]; then
DriverPath="drv:///sample.drv/generic.ppd"
exit 1
fi
- # Try to determine if the necessary printer drivers are installed, and set alternate driver paths
- # This should match OpenSUSE, and probably SUSE Enterprise, and other derivates that use yast2 as the primary package
- if command -v yast2 >/dev/null 2>&1; then
+ # Test if secret-tool is installed
+ if ! command -v secret-tool >/dev/null 2>&1; then
+ printerror "You must have secret-tool installed for this script to work. Please install libsecret-tools (Debian-systems) or secret-tool (Fedora/CentOS)."
+ exit 1
+ fi
+
+ # Try to determine if the necessary printer drivers are installed, and set correct driver paths
+
+ # This should match OpenSUSE, and probably SUSE Enterprise, and other derivates that use zypper as the primary package manager
+ if command -v zypper >/dev/null 2>&1; then
if [ "${Driver}" = "postscript" ]; then
- if ! rpm -q OpenPrintingPPDs-postscript >/dev/null 2>&1; then
- printerror "You don't seem to have the correct printer drivers installed, please run:"
- printerror " sudo zypper install OpenPrintingPPDs-postscript"
- printerror "first, or use the generic driver instead."
- exit 1
- else
- if [ "${Model}" = "ricoh" ]; then
- DriverPath="OpenPrintingPPDs/postscript/Ricoh-MP_C6003.Postscript-Ricoh.ppd.gz"
+ if [ "${Model}" = "ricoh" ]; then
+ if ! rpm -q OpenPrintingPPDs-postscript >/dev/null 2>&1; then
+ printerror "You don't seem to have the correct printer drivers installed, please run:"
+ printerror " sudo zypper install OpenPrintingPPDs-postscript"
+ printerror "first, or use the generic driver instead."
+ exit 1
else
- DriverPath="OpenPrintingPPDs/postscript/Generic-PostScript_Printer.Postscript.ppd.gz"
+ DriverPath="OpenPrintingPPDs/postscript/Ricoh-MP_C6003.Postscript-Ricoh.ppd.gz"
fi
+ else
+ DriverPath="Postscript.ppd.gz"
fi
else
if ! rpm -q OpenPrintingPPDs-ghostscript >/dev/null 2>&1; then
fi
fi
fi
- fi
- # The rest of the tests ignore the model test (all other distros support drv:///)
- if [ "${Model}" != "generic" ]; then
- # This should match Fedora and other modern rpm based systems that have dnf as the primary package manager
- if command -v dnf >/dev/null 2>&1; then
- if ! rpm -q foomatic-db-ppds 2>&1; then
- printerror "You don't seem to have the correct printer drivers installed, please run:"
- printerror " sudo dnf install foomatic-db-ppds"
- printerror "first, or use the generic driver instead."
- exit 1
- else
- if [ "${Driver}" = "postscript" ]; then
- DriverPath="foomatic-db-ppds/Ricoh/PS/Ricoh-MP_C6003_PS.ppd.gz"
+ else
+ # The rest of the systems can use drv:/// paths for the generic drivers, but we need to detect various distros for advice on installing Ricoh drivers
+ if [ "${Model}" = "ricoh" ]; then
+ # This should match Fedora and other modern rpm based systems that have dnf as the primary package manager
+ if command -v dnf >/dev/null 2>&1; then
+ if ! rpm -q foomatic-db-ppds 2>&1; then
+ printerror "You don't seem to have the correct printer drivers installed, please run:"
+ printerror " sudo dnf install foomatic-db-ppds"
+ printerror "first, or use the generic driver instead."
+ exit 1
else
- DriverPath="foomatic-db-ppds/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd.gz"
+ if [ "${Driver}" = "postscript" ]; then
+ DriverPath="foomatic-db-ppds/Ricoh/PS/Ricoh-MP_C6003_PS.ppd.gz"
+ else
+ DriverPath="foomatic-db-ppds/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd.gz"
+ fi
fi
fi
- fi
- # This should match CentOS, RHEL and other RHEL based distros that have yum as the primary package manager
- if command -v yum >/dev/null 2>&1; then
- if ! rpm -q foomatic-db-ppds >/dev/null 2>&1; then
- printerror "You don't seem to have the correct printer drivers installed, please run:"
- printerror " sudo yum install foomatic-db-ppds"
- printerror "first, or use the generic driver instead."
- exit 1
- else
- if [ "${Driver}" = "postscript" ]; then
- DriverPath="foomatic-db-ppds/Ricoh/PS/Ricoh-MP_C6003_PS.ppd.gz"
+ # This should match CentOS, RHEL and other RHEL based distros that have yum as the primary package manager
+ if command -v yum >/dev/null 2>&1; then
+ if ! rpm -q foomatic-db-ppds >/dev/null 2>&1; then
+ printerror "You don't seem to have the correct printer drivers installed, please run:"
+ printerror " sudo yum install foomatic-db-ppds"
+ printerror "first, or use the generic driver instead."
+ exit 1
else
- DriverPath="foomatic-db-ppds/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd.gz"
+ if [ "${Driver}" = "postscript" ]; then
+ DriverPath="foomatic-db-ppds/Ricoh/PS/Ricoh-MP_C6003_PS.ppd.gz"
+ else
+ DriverPath="foomatic-db-ppds/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd.gz"
+ fi
fi
fi
- fi
- # This should match Debian, Ubuntu and most if not all derivates that use dpkg as the primary package manager
- if command -v dpkg >/dev/null 2>&1; then
- if ! dpkg -s openprinting-ppds > /dev/null 2>&1; then
- printerror "You must have the correct printer drivers installed, please run:"
- printerror " sudo apt-get install openprinting-ppds"
- printerror "first, or use the generic driver instead."
- exit 1
- else
- if [ "${Driver}" = "postscript" ]; then
- DriverPath="openprinting-ppds:0/ppd/openprinting/Ricoh/PS/Ricoh-MP_C6003_PS.ppd"
- else
- DriverPath="openprinting-ppds:0/ppd/openprinting/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd"
+ # This should match Debian, Ubuntu and most if not all derivates that use dpkg as the primary package manager
+ if command -v dpkg >/dev/null 2>&1; then
+ if ! dpkg -s openprinting-ppds > /dev/null 2>&1; then
+ printerror "You must have the correct printer drivers installed, please run:"
+ printerror " sudo apt-get install openprinting-ppds"
+ printerror "first, or use the generic driver instead."
+ exit 1
+ else
+ if [ "${Driver}" = "postscript" ]; then
+ DriverPath="openprinting-ppds:0/ppd/openprinting/Ricoh/PS/Ricoh-MP_C6003_PS.ppd"
+ else
+ DriverPath="openprinting-ppds:0/ppd/openprinting/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd"
+ fi
fi
fi
fi
fi
echo "This script will add a new printer called ${QueueName}, connecting to the
-print server ${PrintServer} using your normal user name and
-password from NTNU."
+print server ${PrintServer} using your user name and password from NTNU."
# Get username and password
printf "User name: "
-read Username
+read -r Username
printf "Password: "
Settings=$(stty -g)
stty -echo
-read Password
+read -r Password
stty "${Settings}"
echo ""
# Some further tests for Linux systems
if [ "${Uname}" = "linux" ]; then
- echo -e "\nNOTE: Your credentials will be stored in plaintext in /etc/cups/printers.conf.\nThis file us usually not readable for normal users, but still:\nDo not use this script on multi user systems!"
- # Test for valid username and password if on Linux
+ # Test for valid username and password
# Bonus: find out if the print share is actually available
PrintServerIP=$(getent ahostsv4 ${PrintServer} | head -n 1 | cut -d " " -f 1)
- smbclient -U "${Workgroup}/${Username}%${Password}" -L "//${PrintServer}" -I "${PrintServerIP}" > /dev/null 2>&1
- if [ $? -ne 0 ]; then
+ if ! smbclient -U "${Workgroup}/${Username}%${Password}" -L "//${PrintServer}" -I "${PrintServerIP}" > /dev/null 2>&1; then
printerror "User name or password incorrect, or no contact with the print server ${PrintServer}."
exit 1
fi
- ShareFound=$(smbclient -U "${Workgroup}/${Username}%${Password}" -L "//${PrintServer}" -I "${PrintServerIP}" -g 2>/dev/null | grep ${PrintShare} | cut -d "|" -f 1)
+ ShareFound=$(smbclient -U "${Workgroup}/${Username}%${Password}" -L "//${PrintServer}" -I "${PrintServerIP}" -g 2>/dev/null | grep ${PrintFile} | cut -d "|" -f 1)
if [ "${ShareFound}" != "Printer" ]; then
- printerror "Could not find printer share called ${PrintShare} on the server"
+ printerror "Could not find printer share called ${PrintFile} on the server"
printerror "This script must be broken or outdated. Please contact orakel@ntnu.no for further assistance."
exit 1
fi
# Similar tests for OSX
if [ "${Uname}" = "darwin" ]; then
- smbutil view -A "//${Workgroup};${Username}:${Password}@${PrintServer}" > /dev/null 2>&1
- if [ $? -ne 0 ]; then
+ if ! smbutil view -A "//${Workgroup};${Username}:${Password}@${PrintServer}" > /dev/null 2>&1; then
printerror "User name or password incorrect, or no contact with the print server ${PrintServer}."
exit 1
fi
- ShareFound=$(smbutil view "//${Workgroup};${Username}:${Password}@${PrintServer}" 2>/dev/null | grep ${PrintShare} | cut -d " " -f 1)
- if [ "${ShareFound}" != "${PrintShare}" ]; then
- printerror "Could not find printer share called ${PrintShare} on the server"
+ ShareFound=$(smbutil view "//${Workgroup};${Username}:${Password}@${PrintServer}" 2>/dev/null | grep ${PrintFile} | cut -d " " -f 1)
+ if [ "${ShareFound}" != "${PrintFile}" ]; then
+ printerror "Could not find printer share called ${PrintFile} on the server"
printerror "This script must be broken or outdated. Please contact orakel@ntnu.no for further assistance."
exit 1
fi
fi
-# Finally we can add the printer
+# Finally we can add the printer, let's remove any existing printer share with the same name first
+lpadmin -x ${QueueName} > /dev/null 2&>1
# The Linux way
if [ "${Uname}" = "linux" ]; then
- lpadmin -p ${QueueName} \
+ if [ "${Plaintext}" = "YES" ]; then
+ PrinterShare="smb://${Username}:${Password}@${Workgroup}/${PrintServer}/${PrintFile}"
+ AuthInfo="none"
+ echo -e "\nNOTE: Your credentials will be stored in plaintext in /etc/cups/printers.conf.\nThis is usually only necessary on headless systems or on systems that don't run a dbus-daemon and/or a keyring that can provide the org.freedesktop.secrets service.\nNeedless to say, this is not a good idea on multi-user systems.\n"
+ else
+ PrinterShare="smb://${Workgroup}/${PrintServer}/${PrintFile}"
+ AuthInfo="username,password"
+ fi
+ if ! lpadmin -p ${QueueName} \
-D "FollowMe print queue at NTNU" \
- -v "smb://${Username}:${Password}@${Workgroup}/${PrintServer}/${PrintShare}" \
+ -v "${PrinterShare}" \
-m "${DriverPath}" \
- -u allow:all -E
+ -o auth-info-required="$AuthInfo" \
+ -u allow:all -E; then
+ printerror "Could not connect to printer share. See above error for details."
+ exit 1
+ fi
+ if [ "${Plaintext}" != "YES" ]; then
+ # Add credentials to the keyring
+ if ! echo -n "${Password}" | secret-tool store \
+ --label "ipp://localhost:631/printers/$QueueName" \
+ uri "ipp://localhost:631/printers/${QueueName}" \
+ user "${Username}"; then
+ printerror "Could not store credentials to the keyring, see above error for details. A workaround can be to use the option --plaintext"
+ fi
+ fi
fi
# The OSX way
if [ "${Uname}" = "darwin" ]; then
- lpadmin -p ${QueueName} \
+ if ! lpadmin -p ${QueueName} \
-D "FollowMe print queue at NTNU" \
- -v "smb://${PrintServer}/${PrintShare}" \
+ -v "smb://${PrintServer}/${PrintFile}" \
-m "${DriverPath}" \
-o printer-is-shared=false -o printer-op-policy=authenticated \
- -u allow:all -E
+ -u allow:all -E; then
+ printerror "Could not connect to printer share. See above error for details."
+ exit 1
+ fi
cupsenable "${QueueName}"
cupsaccept "${QueueName}"
# Add credentials to the keychain if they are missing
- # Shamelessly stolen from https://github.com/Orakeltjenesten/scripts/blob/33abfb353524f449f0bbdee27adb2f1f0a9756a2/print/ntnuprint-mac.sh
+ # Shamelessly stolen^W^WBorrowed from https://github.com/Orakeltjenesten/scripts/blob/33abfb353524f449f0bbdee27adb2f1f0a9756a2/print/ntnuprint-mac.sh
+ # TODO: Since we should have a known-good username and password at this stage it's unwise to re-use the existing credentials, can we simply drop the test?
if ! security find-internet-password -s ${PrintServer} >/dev/null 2>&1; then
security -v add-internet-password -a "${Workgroup}\\${Username}" -s ${PrintServer} \
-w "${Password}" -D "Network Password" -r "smb " -l "${QueueName}" \
fi
fi
-if [ $? -ne 0 ]; then
- printerror "Could not connect to printer share. See above error for details."
- exit 1
-fi
-
# Set correct paper size and enable the duplexer option
-lpadmin -p ${QueueName} -o PageSize=A4 -o Option1=True
-
-if [ $? -ne 0 ]; then
+if ! lpadmin -p ${QueueName} -o PageSize=A4 -o Option1=True; then
printerror "Could not set default options on the print queue ${QueueName}. See above error for details."
exit 1
fi
# Set as default
-lpadmin -d ${QueueName}
-
-if [ $? -ne 0 ]; then
+if ! lpadmin -d ${QueueName}; then
printerror "Could not set the print queue ${QueueName} as default printer. See above error for details."
exit 1
fi
-echo "Printer successfully installed."
+echo "Printer successfully installed. You may need to restart cups for the changes to take effect."