Minor fixes
[einar-bin] / addfollowmeprint.sh
1 #!/bin/bash
2 # This script installs the FollowMe print queue at NTNU on Linux and possibly Mac systems.
3 # The targeted and tested distros are: Debian, Ubuntu (and derivates), Fedora, CentOS, OpenSUSE and Mint
4 # Copyright © 2017-2019 einar.haraldseid@ntnu.no
5
6 # Documentation
7 function usage {
8 echo "Usage: ./$(basename "${0}") [OPTIONS]"
9 echo "Options:"
10 echo " -m, --model {ricoh|generic} Printer model to install (default: generic)"
11 echo " -d, --driver {pcl|postscript} Printer driver to use (default: postscript)"
12 echo " -f, --force Force running script as if on Linux systems"
13 echo " -p, --plaintext Store credentials as plaintext in /etc/cups/printers.conf (Linux only)"
14 echo " -h, --help Display this help text"
15 }
16
17 # Print errors to STDERR
18 function printerror() {
19 echo "${*}" 1>&2
20 }
21
22 # Set default options that may be overridden by passed options below
23 Model="generic"
24 Driver="postscript"
25
26 # Set other default options
27 PrintServer="followprint.win.ntnu.no"
28 PrintFile="ntnuprint-ricoh"
29 Workgroup="WIN-NTNU-NO"
30 QueueName="FollowMe"
31
32 while [[ $# -gt 0 ]]; do
33 Key="${1}"
34
35 case ${Key} in
36 -m|--model)
37 Model=$(echo "${2}" | tr "[:upper:]" "[:lower:]")
38 if [ "${Model}" != "ricoh" ] && [ "${Model}" != "generic" ]; then
39 printerror "Unknown model ${Model}, please choose one of ricoh or generic"
40 exit 1
41 fi
42 shift # Jump to next argument
43 ;;
44 -f|--force)
45 Force="YES"
46 shift # Jump to next argument
47 ;;
48 -d|--driver)
49 Driver=$(echo "${2}" | tr "[:upper:]" "[:lower:]")
50 if [ "${Driver}" != "postscript" ] && [ "${Driver}" != "pcl" ]; then
51 printerror "Unknown driver ${Driver}, plase choose one of postscript or pcl"
52 exit 1
53 fi
54 shift # Jump to next argument
55 ;;
56 -p|--plaintext)
57 Plaintext="YES"
58 shift # Jump to next argument
59 ;;
60 -h|--help)
61 usage
62 exit 0
63 ;;
64 *)
65 # Unknown argument
66 echo "Unknown argument: ${Key}"
67 exit 1
68 ;;
69 esac
70
71 shift # past argument or value
72 done
73
74 # Make sure we have sudo powers when we need it
75 if ! sudo -k; then
76 printerror "This script requires sudo to function"
77 exit 1
78 fi
79
80 # But don't run as super user, otherwise we can't access the keyring
81 if [ ${UID} -eq 0 ]; then
82 if [ "${Plaintext}" != "YES" ]; then
83 printerror "Please run this script as your normal user, we will prompt you for your sudo password when needed. Or you can use the --plaintext option"
84 exit 1
85 fi
86 else
87 echo "Please provide sudo password, as some parts of this script requires it"
88 if ! sudo true; then
89 printerror "Sorry, this script requires working sudo privileges to function"
90 exit 1
91 fi
92 fi
93
94 # Test for supported OS
95 Uname=$(uname | tr "[:upper:]" "[:lower:]")
96 if [ "${Uname}" != "darwin" ] && [ "${Uname}" != "linux" ] && [ "${Force}" != "YES" ]; then
97 printerror "I don't think I can run on ${Uname}, but if you insist, please use -f to force Linux detection. This may not work, though."
98 exit 1
99 fi
100
101 # Set Uname to linux if we are forcing running the script
102 if [ "${Force}" = "YES" ]; then
103 Uname="linux"
104 fi
105
106 # Set printer driver path based on driver (we will override these if we're specific distros
107 if [ "${Driver}" = "postscript" ]; then
108 DriverPath="drv:///sample.drv/generic.ppd"
109 else
110 DriverPath="drv:///sample.drv/generpcl.ppd"
111 fi
112
113 # Test for CUPS
114 if ! sudo bash -c "command -v lpadmin" > /dev/null 2>&1; then
115 printerror "You must have CUPS installed to add printers. Please install CUPS."
116 exit 1
117 fi
118
119 # Tests for Linux systems
120 if [ "${Uname}" = "linux" ]; then
121 # Test if smbclient is installed
122 if ! command -v smbclient >/dev/null 2>&1; then
123 printerror "You must have smbclient installed to print to NTNU followprint. Please install smbclient."
124 exit 1
125 fi
126
127 # Test if secret-tool is installed
128 if ! command -v secret-tool >/dev/null 2>&1; then
129 printerror "You must have secret-tool installed for this script to work. Please install libsecret-tools (Debian-systems) or secret-tool (Fedora/CentOS)."
130 exit 1
131 fi
132
133 # Try to determine if the necessary printer drivers are installed, and set correct driver paths
134
135 # This should match OpenSUSE, and probably SUSE Enterprise, and other derivates that use zypper as the primary package manager
136 if command -v zypper >/dev/null 2>&1; then
137 if [ "${Driver}" = "postscript" ]; then
138 if [ "${Model}" = "ricoh" ]; then
139 if ! sudo rpm -q OpenPrintingPPDs-postscript >/dev/null 2>&1; then
140 printerror "You don't seem to have the correct printer drivers installed, please run:"
141 printerror " sudo zypper install OpenPrintingPPDs-postscript"
142 printerror "first, or use the generic model instead."
143 exit 1
144 else
145 DriverPath="OpenPrintingPPDs/postscript/Ricoh-MP_C6003.Postscript-Ricoh.ppd.gz"
146 fi
147 else
148 DriverPath="Postscript.ppd.gz"
149 fi
150 else
151 if ! sudo rpm -q OpenPrintingPPDs-ghostscript >/dev/null 2>&1; then
152 printerror "You don't seem to have the correct printer drivers installed, please run:"
153 printerror " sudo zypper install OpenPrintingPPDs-ghostscript"
154 printerror "first, or use the generic model instead."
155 exit 1
156 else
157 if [ "${Model}" = "ricoh" ]; then
158 DriverPath="OpenPrintingPPDs/ghostscript/Ricoh-MP_C6003.pxlcolor-Ricoh.ppd.gz"
159 else
160 DriverPath="OpenPrintingPPDs/ghostscript/Generic-PCL_6_PCL_XL_Printer.pxlcolor.ppd.gz"
161 fi
162 fi
163 fi
164 else
165 # 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
166 if [ "${Model}" = "ricoh" ]; then
167 # This should match Fedora and other modern rpm based systems that have dnf as the primary package manager
168 if command -v dnf >/dev/null 2>&1; then
169 if ! sudo rpm -q foomatic-db-ppds > /dev/null 2>&1; then
170 printerror "You don't seem to have the correct printer drivers installed, please run:"
171 printerror " sudo dnf install foomatic-db-ppds"
172 printerror "first, or use the generic model instead."
173 exit 1
174 else
175 if [ "${Driver}" = "postscript" ]; then
176 DriverPath="foomatic-db-ppds/Ricoh/PS/Ricoh-MP_C6003_PS.ppd.gz"
177 else
178 DriverPath="foomatic-db-ppds/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd.gz"
179 fi
180 fi
181 # This should match CentOS, RHEL and other RHEL based distros that have yum as the primary package manager
182 elif command -v yum >/dev/null 2>&1; then
183 if ! sudo rpm -q foomatic-filters > /dev/null 2>&1; then
184 printerror "You don't seem to have the foomatic-filters package installed, please run:"
185 printerror " sudo yum install foomatic-filters"
186 printerror "first, or use the generic model instead."
187 exit 1
188 fi
189 if ! sudo rpm -q foomatic-db-ppds > /dev/null 2>&1; then
190 printerror "You don't seem to have the correct printer drivers installed, please run:"
191 printerror " sudo yum install foomatic-db-ppds"
192 printerror "first, or use the generic model instead."
193 exit 1
194 else
195 if [ "${Driver}" = "postscript" ]; then
196 DriverPath="foomatic-db-ppds/Ricoh/PS/Ricoh-MP_C6003_PS.ppd.gz"
197 else
198 DriverPath="foomatic-db-ppds/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd.gz"
199 fi
200 fi
201 fi
202 # This should match Debian, Ubuntu and most if not all derivates that use dpkg as the primary package manager
203 if command -v dpkg >/dev/null 2>&1; then
204 if ! sudo dpkg -s openprinting-ppds > /dev/null 2>&1; then
205 printerror "You must have the correct printer drivers installed, please run:"
206 printerror " sudo apt-get install openprinting-ppds"
207 printerror "first, or use the generic model instead."
208 exit 1
209 else
210 if [ "${Driver}" = "postscript" ]; then
211 DriverPath="openprinting-ppds:0/ppd/openprinting/Ricoh/PS/Ricoh-MP_C6003_PS.ppd"
212 else
213 DriverPath="openprinting-ppds:0/ppd/openprinting/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd"
214 fi
215 fi
216 fi
217 fi
218 fi
219 fi
220
221 echo "This script will add a new printer called ${QueueName}, connecting to the
222 print server ${PrintServer} using your user name and password from NTNU."
223
224 # Get username and password
225 printf "User name: "
226 read -r Username
227 printf "Password: "
228 Settings=$(stty -g)
229 stty -echo
230 read -r Password
231 stty "${Settings}"
232
233 echo ""
234
235 # Some further tests for Linux systems
236 if [ "${Uname}" = "linux" ]; then
237 # Test for valid username and password
238 # Bonus: find out if the print share is actually available
239 PrintServerIP=$(getent ahostsv4 ${PrintServer} | head -n 1 | cut -d " " -f 1)
240 if ! smbclient -U "${Workgroup}/${Username}%${Password}" -L "//${PrintServer}" -I "${PrintServerIP}" > /dev/null 2>&1; then
241 printerror "User name or password incorrect, or no contact with the print server ${PrintServer}."
242 exit 1
243 fi
244 ShareFound=$(smbclient -U "${Workgroup}/${Username}%${Password}" -L "//${PrintServer}" -I "${PrintServerIP}" -g 2>/dev/null | grep ${PrintFile} | cut -d "|" -f 1)
245 if [ "${ShareFound}" != "Printer" ]; then
246 printerror "Could not find printer share called ${PrintFile} on the server"
247 printerror "This script must be broken or outdated. Please contact orakel@ntnu.no for further assistance."
248 exit 1
249 fi
250 fi
251
252 # Similar tests for OSX
253 if [ "${Uname}" = "darwin" ]; then
254 if ! smbutil view -A "//${Workgroup};${Username}:${Password}@${PrintServer}" > /dev/null 2>&1; then
255 printerror "User name or password incorrect, or no contact with the print server ${PrintServer}."
256 exit 1
257 fi
258 ShareFound=$(smbutil view "//${Workgroup};${Username}:${Password}@${PrintServer}" 2>/dev/null | grep ${PrintFile} | cut -d " " -f 1)
259 if [ "${ShareFound}" != "${PrintFile}" ]; then
260 printerror "Could not find printer share called ${PrintFile} on the server"
261 printerror "This script must be broken or outdated. Please contact orakel@ntnu.no for further assistance."
262 exit 1
263 fi
264 fi
265
266 # Finally we can add the printer, let's remove any existing printer share with the same name first
267 sudo lpadmin -x ${QueueName} > /dev/null 2>&1
268
269 # The Linux way
270 if [ "${Uname}" = "linux" ]; then
271 if [ "${Plaintext}" = "YES" ]; then
272 PrinterShare="smb://${Workgroup}/${Username}:${Password}@${PrintServer}/${PrintFile}"
273 AuthInfo="none"
274 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"
275 else
276 PrinterShare="smb://${Workgroup}/${PrintServer}/${PrintFile}"
277 AuthInfo="username,password"
278 fi
279 if ! sudo lpadmin -p ${QueueName} \
280 -D "FollowMe print queue at NTNU" \
281 -L "Many locations" \
282 -v "${PrinterShare}" \
283 -m "${DriverPath}" \
284 -o auth-info-required="$AuthInfo" \
285 -u allow:all -E; then
286 printerror "Could not connect to printer share. See above error for details."
287 exit 1
288 fi
289 if [ "${Plaintext}" != "YES" ]; then
290 # Add credentials to the keyring
291 if ! echo -n "${Password}" | secret-tool store \
292 --label "ipp://localhost:631/printers/$QueueName" \
293 uri "ipp://localhost:631/printers/${QueueName}" \
294 user "${Username}"; then
295 printerror "Could not store credentials to the keyring, see above error for details. A workaround can be to use the option --plaintext"
296 fi
297 fi
298 fi
299
300 # The OSX way
301 if [ "${Uname}" = "darwin" ]; then
302 if ! sudo lpadmin -p ${QueueName} \
303 -D "FollowMe print queue at NTNU" \
304 -L "Many locations" \
305 -v "smb://${PrintServer}/${PrintFile}" \
306 -m "${DriverPath}" \
307 -o printer-is-shared=false -o printer-op-policy=authenticated \
308 -u allow:all -E; then
309 printerror "Could not connect to printer share. See above error for details."
310 exit 1
311 fi
312
313 sudo cupsenable "${QueueName}"
314 sudo cupsaccept "${QueueName}"
315
316 # Add credentials to the keychain if they are missing
317 # Shamelessly stolen^W^WBorrowed from https://github.com/Orakeltjenesten/scripts/blob/33abfb353524f449f0bbdee27adb2f1f0a9756a2/print/ntnuprint-mac.sh
318 # 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?
319 if ! security find-internet-password -s ${PrintServer} >/dev/null 2>&1; then
320 security -v add-internet-password -a "${Workgroup}\\${Username}" -s ${PrintServer} \
321 -w "${Password}" -D "Network Password" -r "smb " -l "${QueueName}" \
322 -T /System/Library/CoreServices/NetAuthAgent.app -T 'group://NetAuth' \
323 -T /System/Library/CoreServices/NetAuthAgent.app/Contents/MacOS/NetAuthSysAgent >/dev/null 2>&1
324 fi
325 fi
326
327 # Set correct paper size and enable the duplexer option
328 if ! sudo lpadmin -p ${QueueName} -o PageSize=A4 -o Option1=True; then
329 printerror "Could not set default options on the print queue ${QueueName}. See above error for details."
330 exit 1
331 fi
332
333 # Set as default
334 if ! sudo lpadmin -d ${QueueName}; then
335 printerror "Could not set the print queue ${QueueName} as default printer. See above error for details."
336 exit 1
337 fi
338
339 echo "Printer successfully installed."
340
341 if [ "${Uname}" = "linux" ] && [ "${Plaintext}" != "YES" ]; then
342 echo -e "\nPlease note: due to the way credentials are stored and accessed on Linux, some print operations will still halt for credentials, notably the \"Print test page\" function. In those cases, supply your normal NTNU username and password."
343 fi