53937aa03d4783b97b1408a29a37f0a5e8d57b6b
[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 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 fi
182 # This should match CentOS, RHEL and other RHEL based distros that have yum as the primary package manager
183 if command -v yum >/dev/null 2>&1; then
184 if ! sudo rpm -q foomatic-filters >/dev/null 2>&1; then
185 printerror "You don't seem to have the foomatic-filters package installed, please run:"
186 printerror " sudo yum install foomatic-filters"
187 printerror "first, or use the generic model instead."
188 exit 1
189 fi
190 if ! sudo rpm -q foomatic-db-ppds >/dev/null 2>&1; then
191 printerror "You don't seem to have the correct printer drivers installed, please run:"
192 printerror " sudo yum install foomatic-db-ppds"
193 printerror "first, or use the generic model instead."
194 exit 1
195 else
196 if [ "${Driver}" = "postscript" ]; then
197 DriverPath="foomatic-db-ppds/Ricoh/PS/Ricoh-MP_C6003_PS.ppd.gz"
198 else
199 DriverPath="foomatic-db-ppds/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd.gz"
200 fi
201 fi
202 fi
203 # This should match Debian, Ubuntu and most if not all derivates that use dpkg as the primary package manager
204 if command -v dpkg >/dev/null 2>&1; then
205 if ! sudo dpkg -s openprinting-ppds > /dev/null 2>&1; then
206 printerror "You must have the correct printer drivers installed, please run:"
207 printerror " sudo apt-get install openprinting-ppds"
208 printerror "first, or use the generic model instead."
209 exit 1
210 else
211 if [ "${Driver}" = "postscript" ]; then
212 DriverPath="openprinting-ppds:0/ppd/openprinting/Ricoh/PS/Ricoh-MP_C6003_PS.ppd"
213 else
214 DriverPath="openprinting-ppds:0/ppd/openprinting/Ricoh/PXL/Ricoh-MP_C6003_PXL.ppd"
215 fi
216 fi
217 fi
218 fi
219 fi
220 fi
221
222 echo "This script will add a new printer called ${QueueName}, connecting to the
223 print server ${PrintServer} using your user name and password from NTNU."
224
225 # Get username and password
226 printf "User name: "
227 read -r Username
228 printf "Password: "
229 Settings=$(stty -g)
230 stty -echo
231 read -r Password
232 stty "${Settings}"
233
234 echo ""
235
236 # Some further tests for Linux systems
237 if [ "${Uname}" = "linux" ]; then
238 # Test for valid username and password
239 # Bonus: find out if the print share is actually available
240 PrintServerIP=$(getent ahostsv4 ${PrintServer} | head -n 1 | cut -d " " -f 1)
241 if ! smbclient -U "${Workgroup}/${Username}%${Password}" -L "//${PrintServer}" -I "${PrintServerIP}" > /dev/null 2>&1; then
242 printerror "User name or password incorrect, or no contact with the print server ${PrintServer}."
243 exit 1
244 fi
245 ShareFound=$(smbclient -U "${Workgroup}/${Username}%${Password}" -L "//${PrintServer}" -I "${PrintServerIP}" -g 2>/dev/null | grep ${PrintFile} | cut -d "|" -f 1)
246 if [ "${ShareFound}" != "Printer" ]; then
247 printerror "Could not find printer share called ${PrintFile} on the server"
248 printerror "This script must be broken or outdated. Please contact orakel@ntnu.no for further assistance."
249 exit 1
250 fi
251 fi
252
253 # Similar tests for OSX
254 if [ "${Uname}" = "darwin" ]; then
255 if ! smbutil view -A "//${Workgroup};${Username}:${Password}@${PrintServer}" > /dev/null 2>&1; then
256 printerror "User name or password incorrect, or no contact with the print server ${PrintServer}."
257 exit 1
258 fi
259 ShareFound=$(smbutil view "//${Workgroup};${Username}:${Password}@${PrintServer}" 2>/dev/null | grep ${PrintFile} | cut -d " " -f 1)
260 if [ "${ShareFound}" != "${PrintFile}" ]; then
261 printerror "Could not find printer share called ${PrintFile} on the server"
262 printerror "This script must be broken or outdated. Please contact orakel@ntnu.no for further assistance."
263 exit 1
264 fi
265 fi
266
267 # Finally we can add the printer, let's remove any existing printer share with the same name first
268 sudo lpadmin -x ${QueueName} > /dev/null 2>&1
269
270 # The Linux way
271 if [ "${Uname}" = "linux" ]; then
272 if [ "${Plaintext}" = "YES" ]; then
273 PrinterShare="smb://${Workgroup}/${Username}:${Password}@${PrintServer}/${PrintFile}"
274 AuthInfo="none"
275 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"
276 else
277 PrinterShare="smb://${Workgroup}/${PrintServer}/${PrintFile}"
278 AuthInfo="username,password"
279 fi
280 if ! sudo lpadmin -p ${QueueName} \
281 -D "FollowMe print queue at NTNU" \
282 -L "Many locations" \
283 -v "${PrinterShare}" \
284 -m "${DriverPath}" \
285 -o auth-info-required="$AuthInfo" \
286 -u allow:all -E; then
287 printerror "Could not connect to printer share. See above error for details."
288 exit 1
289 fi
290 if [ "${Plaintext}" != "YES" ]; then
291 # Add credentials to the keyring
292 if ! echo -n "${Password}" | secret-tool store \
293 --label "ipp://localhost:631/printers/$QueueName" \
294 uri "ipp://localhost:631/printers/${QueueName}" \
295 user "${Username}"; then
296 printerror "Could not store credentials to the keyring, see above error for details. A workaround can be to use the option --plaintext"
297 fi
298 fi
299 fi
300
301 # The OSX way
302 if [ "${Uname}" = "darwin" ]; then
303 if ! sudo lpadmin -p ${QueueName} \
304 -D "FollowMe print queue at NTNU" \
305 -L "Many locations" \
306 -v "smb://${PrintServer}/${PrintFile}" \
307 -m "${DriverPath}" \
308 -o printer-is-shared=false -o printer-op-policy=authenticated \
309 -u allow:all -E; then
310 printerror "Could not connect to printer share. See above error for details."
311 exit 1
312 fi
313
314 sudo cupsenable "${QueueName}"
315 sudo cupsaccept "${QueueName}"
316
317 # Add credentials to the keychain if they are missing
318 # Shamelessly stolen^W^WBorrowed from https://github.com/Orakeltjenesten/scripts/blob/33abfb353524f449f0bbdee27adb2f1f0a9756a2/print/ntnuprint-mac.sh
319 # 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?
320 if ! security find-internet-password -s ${PrintServer} >/dev/null 2>&1; then
321 security -v add-internet-password -a "${Workgroup}\\${Username}" -s ${PrintServer} \
322 -w "${Password}" -D "Network Password" -r "smb " -l "${QueueName}" \
323 -T /System/Library/CoreServices/NetAuthAgent.app -T 'group://NetAuth' \
324 -T /System/Library/CoreServices/NetAuthAgent.app/Contents/MacOS/NetAuthSysAgent >/dev/null 2>&1
325 fi
326 fi
327
328 # Set correct paper size and enable the duplexer option
329 if ! sudo lpadmin -p ${QueueName} -o PageSize=A4 -o Option1=True; then
330 printerror "Could not set default options on the print queue ${QueueName}. See above error for details."
331 exit 1
332 fi
333
334 # Set as default
335 if ! sudo lpadmin -d ${QueueName}; then
336 printerror "Could not set the print queue ${QueueName} as default printer. See above error for details."
337 exit 1
338 fi
339
340 echo "Printer successfully installed."
341
342 if [ "${Uname}" = "linux" ] && [ "${Plaintext}" != "YES" ]; then
343 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."
344 fi