Posted on 04-10-2015 03:44 PM
So what I've been tasked with is preventing everybody but one specific department in our company from printing to a Splash RIP that belongs to the department in question. I already have the dept. set up in Casper as a department, I already have the printer in question set up as a printer in Casper. Installing it via casper works great, and as long as it was installed by casper, then removing it by casper via the unmap printer function works great too.
The issue is that all these people from other departments added the splash rip to their Macs on their own. And this has been going on since before we had casper in house, so yes it's an organizational nightmare but the main problem is that since the casper unmap function uses the CUPS name, it can't unmap the printer unless the name is exactly what I specify when I set up the printer.
For example, I set it up in casper as Studio Splash, but if somebody in some other dept added it to their own machine and called it Splash, or Studio Printer, or RIP, the unmap function will not work to remove it from their Mac because the CUPS name is not the same as what is specified in Casper.
So my question is, is there a way to identify an installed printer on a Mac by using the IP address it's pointing to? Or some other metric other than the CUPS name? Or is there another way altogether to prevent anybody who is not in a specified group from printing to that printer? I've tested using the casper unmap function and I've looked at the lpadmin command, but I don't have any context for the flags - can I use one of the -u flags in this case? Eventually I will have these things available in self service so I have more control over it but for now I need to find a way to stop people from other depts from printing to this RIP. Anybody have experience with this?
Solved! Go to Solution.
Posted on 04-16-2015 11:03 AM
@znilsson I would look at disabling any broadcasting the printer may be doing as a first line of defense as suggested. If thats an option, it should stop most cases of unauthorized connections. However, its possible some of the users already know the printer's IP address and may be able to add it back in.
Never mind. Didn't see your post as I was composing mine.
Another thing that could work is a LaunchDaemon and a script. Here's something I just whipped together as a test.
First, the LaunchDaemon:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.org.lpstatcheck</string>
<key>Program</key>
<string>/Library/Scripts/dl_printer.sh</string>
<key>RunAtLoad</key>
<true/>
<key>WatchPaths</key>
<array>
<string>/private/etc/cups/ppd</string>
</array>
</dict>
</plist>
It uses a WatchPath of /private/etc/cups/ppd which should get modified each time a printer is added to the Mac.
Now the script.
This example script only looks for a single printer by its IP address of "10.10.10.10" as a simple example) (as you mentioned they always have the IP as part of the name that appears in lpstat -v) If it sees a match, it gets the printer's actual name and does a lpadmin -x to delete it. Because its using a WatchPath, its immediate. Make the modifications you need in the script by changing the "10.10.10.10" example IP to whatever the IP address is for your specific printer in question. Then deploy it to a location like /Library/Scripts/ as a test (may want to bury it somewhere else for actual deployment if you decided to do it this way)
Make sure to change the LaunchDaemon's Program line to match the path of where the script will be located.
#!/bin/bash
IP="10.10.10.10"
for printer in $(lpstat -v); do
if [[ "$printer" =~ "$IP" ]]; then
printer_name=$(lpstat -v | grep "$IP" | awk '{print $3}' | sed 's/://')
lpadmin -x "$printer_name"
fi
done
If you can't or are not able to stop the Bonjour broadcasting as suggested, this may help stop the printer from being added on those Macs. Its actually pretty cool to watch it. Open System Preferences > Printers & Scanners, add in the printer and watch it go *poof* a second later. :)
Posted on 04-10-2015 03:50 PM
I guess you can't charge back for output?
Posted on 04-10-2015 03:54 PM
Yeah, they just don't want anybody printing to it, other than their own dept. Probably has to do mostly with cost, but it could also be printer traffic, like if somebody's trying to get a proof out but some melvin from upstairs is printing War and Peace.
Posted on 04-10-2015 10:47 PM
I have a script for finding and removing specific printers, it's actually pretty easy using lpstat and lpadmin commands to identify and then modify as required.
I'll try and remember to post some of the details come Monday unless someone else provides something better before then.
Posted on 04-11-2015 08:29 AM
type in Terminal "lpstat -v" which gives you the printer name and URI
then remove said printer using:
lpadmin -x "printer_name_here"
An alternative is if the Splash RIP is a Windows machine you can try to use the security properties of the shared print queue to restrict who has access to the printer. But that depends on how people are connecting to the printer.
Posted on 04-12-2015 02:19 PM
lpstat -v | awk '/PRINTERNAME/ {print $3}' | sed 's/://' | xargs -n1 lpadmin -x
Will find any printer with PRINTERNAME in the name and remove it.
Posted on 04-16-2015 09:15 AM
No luck so far - part of the problem is not only do I not know what people have named the printer that they set up, but I also don't know which machines to look at, because I don't even know who is printing to this printer outside of the dept. that owns it.
So manually running lpstat -v does show me the list of printers, but if I don't know which computers to run it on. I was trying for a more enterprise-friendly solution so I could hit all the Macs enrolled in Casper with it.
@Look , I tried that script but the problem is that we don't know the printer name up front. It could be anything, and lpstat shows all installed printers, not just the one I'm looking for. But lpstat also shows the IP address of the printers, and that's just about the only static information I have, the IP address of the RIP. If there were a way to run lpstat, look for that specific IP address and then remove any printer associated with that IP, that would probably work en masse.
I can't think of any other way to do it. And even then I would have to set it run once a day, to continually purge that printer from people who keep attempting to install it. And even then, once a day might not be enough, haha. There just doesn't appear to be any good way of just locking out a specific printer so nobody can print to it.
Posted on 04-16-2015 10:17 AM
Most edu and other orgs that are trying to manage this are using PaperCut for printer accounting...
http://www.papercut.com
Posted on 04-16-2015 10:22 AM
@znilsson, is the SplashRIP advertising itself on the network using the Bonjour Protocol? If it is, I would suggest turning that off on the device and making sure that you can only add or print to the printer using IP based printing. We had an issue with people adding some of our high-speed print shop devices to their Macs and we decided to turn off Bonjour on the printer RIP so it can only be added either manually or by adding the printer through Self Service. This approach might also work for you.
Posted on 04-16-2015 10:34 AM
@RobertHammen Thanks, I'll keep that as an option - but I doubt they're going to want to pay for it. I think they just want me to flip a switch and make it happen, haha.
@mpermann It's using bonjour but bonjour only works on its local vlan, and its local vlan is restricted to the department that owns the printer so that isn't the issue. Everyone else who is printing to it from other departments has installed the printer using the IP address. Yeah it's a mess.
Posted on 04-16-2015 11:03 AM
@znilsson I would look at disabling any broadcasting the printer may be doing as a first line of defense as suggested. If thats an option, it should stop most cases of unauthorized connections. However, its possible some of the users already know the printer's IP address and may be able to add it back in.
Never mind. Didn't see your post as I was composing mine.
Another thing that could work is a LaunchDaemon and a script. Here's something I just whipped together as a test.
First, the LaunchDaemon:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.org.lpstatcheck</string>
<key>Program</key>
<string>/Library/Scripts/dl_printer.sh</string>
<key>RunAtLoad</key>
<true/>
<key>WatchPaths</key>
<array>
<string>/private/etc/cups/ppd</string>
</array>
</dict>
</plist>
It uses a WatchPath of /private/etc/cups/ppd which should get modified each time a printer is added to the Mac.
Now the script.
This example script only looks for a single printer by its IP address of "10.10.10.10" as a simple example) (as you mentioned they always have the IP as part of the name that appears in lpstat -v) If it sees a match, it gets the printer's actual name and does a lpadmin -x to delete it. Because its using a WatchPath, its immediate. Make the modifications you need in the script by changing the "10.10.10.10" example IP to whatever the IP address is for your specific printer in question. Then deploy it to a location like /Library/Scripts/ as a test (may want to bury it somewhere else for actual deployment if you decided to do it this way)
Make sure to change the LaunchDaemon's Program line to match the path of where the script will be located.
#!/bin/bash
IP="10.10.10.10"
for printer in $(lpstat -v); do
if [[ "$printer" =~ "$IP" ]]; then
printer_name=$(lpstat -v | grep "$IP" | awk '{print $3}' | sed 's/://')
lpadmin -x "$printer_name"
fi
done
If you can't or are not able to stop the Bonjour broadcasting as suggested, this may help stop the printer from being added on those Macs. Its actually pretty cool to watch it. Open System Preferences > Printers & Scanners, add in the printer and watch it go *poof* a second later. :)
Posted on 04-16-2015 11:11 AM
@znilsson, why not change the IP address of the RIP and then setup the device in Casper with the new IP address and have everyone in the department re-add the printer. That way anyone that already added the device using the old IP address would no longer be able to print to the device. While it's annoying to have to change the IP address of the device, it would be a quick and easy way to resolve the issue.
Posted on 04-16-2015 11:22 AM
@mm2270 posted his solution as I was writing my suggestion. Mike's a scripting guru and almost always has a neat way to solve an issue. I quite like his solution, it's more fun than mine. With my solution, there is a chance the IP address of the RIP could leak to unauthorized individuals and they could add the printer back. Mike's solution will likely result in a call to the help desk where the unauthorized user will ask why they can't get the printer added. That could be a fun conversation to listen to.
Posted on 04-16-2015 11:30 AM
@mm2270 Holy crap that's amazing. "I just whipped together", haha. Thank you for spending that time on this problem. From looking at it it looks like it'll do exactly what I need it to do, I'll see if I can get it set up and tested today or tomorrow. Also thank you for the very clear instructions on how to use it.
@mpermann Yeah the problem is they'll just walk down into the studio where the printer is and ask somebody what the IP address is, that's how they got it in the first place, haha. It's a nice color laser with a RIP front end that can do 11x17, so people tend to find a way to print to it.
Posted on 04-16-2015 11:43 AM
@znilsson, report back on that first support call you get from one of the unauthorized users that can't get the printer added. I'm sure that will be a hoot. :-)
Posted on 04-16-2015 04:53 PM
@mm2270 Okay, I set everything up and the dl_printer.sh works perfectly - just to test it I ran it in terminal, my Splash printer instantly disappeared. Perfect. And I tried renaming it different things, the script made it go away every time regardless of what I named it.
But I haven't been able to get the launchdaemon to work yet. I used a pre-existing launchdaemon as a template and just replaced the contents with your above launchdaemon script, then I put it in Library/LaunchDaemons and rebooted. Since you already tested it and it worked for you, I'm sure I just did something wrong somewhere. So either that launchd isn't running, or it's not seeing the script or something. I put the script in Library/Scripts for testing, so I could just leave the script as you wrote it. I did try adding the splash printer a few times to trigger it, but nothing happened. Running the script on its own in terminal worked to delete it every time.
It's probably something obvious. Does the launchd filename need to mirror the label? Or can it be anything in the form of com.*.plist? I called it com.mm2270.watchprinter.plist. I haven't set up a watchpath before so it could be something really simple that I'm doing wrong.
Posted on 04-16-2015 05:31 PM
Is /Library/LaunchDaemons/com.mm2270.watchprinter.plist owned by root:wheel, permissions 644 IIRC?
what is the result of sudo launchctl load /Library/LaunchDaemons/com.mm2270.watchprinter.plist
Posted on 04-16-2015 05:43 PM
@znilsson As @RobertHammen mentioned, the most likely culprit is permissions. When you overwrite the existing plist you probably made yourself the owner of it, and the parent launchd process won't have it. It's very particular about permissions and ownership of Launchd plists. Needs to be owned by root:wheel and 644 for POSIX permissions.
It's for this reason I tend to write my Launchd jobs in an app like LaunchControl. Not only does it make sure the settings are correct, it corrects any formatting issues and also shows any load errors in the app, so it's easy to diagnose stuff. But go ahead and correct the permissions and ownership and try it again.
Posted on 04-17-2015 09:05 AM
@RobertHammen @mm2270 That was it, thanks guys. You nailed it precisely, that's exactly what happened. I had used Coda to make the plist but I wasn't aware of the permissions requirements at the time. I opened it back up in coda, reset the permissions to 644 and root:wheel, then replaced the launchd in Composer, which also verified 644 and root:wheel on the file before I re-packaged it.
I set up my splash printer on my test machine, then used casper remote to install the package while I was looking at the Library/LaunchDaemons folder and the Library/Scripts folder. I saw the launchd and the script pop into their respective folders, and then I saw the printer disappear. :) I think I may have actually giggled a little bit.
I did find one circumstance in which it doesn't work though - if I use Casper to install the splash printer, for some reason the launchd doesn't remove it. If I install the printer manually by IP, it gets removed immediately. The PPD is still installed into /private/etc/cups/ppd, but it looks like a couple of jamf launchds also pop up and disappear during the process, maybe they're interfering with it. lpstat verifies that the printer is still being set up with the same IP address. However if I reboot the machine, when it comes back up the printer is gone. So the launchd and script are still working to remove the printer installed by casper, just not at the time it gets installed, something about the other launchds that pop up probably.
But this isn't really an issue because I will not be installing the splash printer for anybody outside this department, by their request, so the only way they would be able to install it would be to do it manually at which point the launchd and script will remove it. Just thought I'd mention it, it will still do exactly what I need it to do as is.
Posted on 04-17-2015 10:02 AM
Hi @znilsson I'm glad you got it working.
I did want to point out one thing that might trip you up. In your case above, I believe the reason it ran the LaunchDaemon immediately after repackaging it and pushing it via Casper Remote is that there was already a Daemon on that Mac from your previous package. launchd probably remembered the load state and just loaded the new plist job as soon as it landed on disk.
What I'd do to make sure the LaunchDaemon gets activated immediately from your package install is add a postinstall or postflight script into the package in Composer. Add the following line below, which should ensure the LaunchDaemon gets loaded right away. Otherwise it will be on disk, but inactive until a user reboots. In fact, that is likely exactly what happened when you pushed it to the other test Mac from Casper Remote. It placed it into the right location, but it didn't load until after the reboot, at which point it removed the printer. So add this in to the postinstall/postflight script, and rebuild the package.
/bin/launchctl load /Library/LaunchDaemons/com.mm2270.watchprinter.plist
Report back on that if you could. In my experience since LaunchDaemons run in a root context, loading them with launchctl from a post script always works. LaunchAgents on the other hand usually need to be loaded in the logged in user's context, since that's where they work.
P.S. - I've had better luck with postflight scripts as opposed to postinstall ones for some reason, but the former only works with bundle style packages, not flat ones. YMMV.
Posted on 04-17-2015 01:53 PM
OK. I did that, set it up as a postinstall script for a flat package, reloaded the pkg into Casper Admin. I removed the launchd and script from the test Mac and rebooted it to make sure the launchd wasn't running, then I added the printer. Then I pushed the SplashWatch pkg to the test machine via Casper Remote. I watched it place the files in the right places and the printer immediately disappeared, so I'm assuming that means the postinstall line worked.
But after that I tried adding the printer again via Casper Remote, and it stayed installed, the launchd/script didn't remove it. But I know the launchd was still active, because I deleted the printer manually and then added the printer manually, and it immediately disappeared. Added it via Casper and it stayed there, added it manually and it disappeared. That's repeatable so it seems like something the Casper Remote install is doing is preventing the launchd from seeing that something has been added to the PPD folder.
After installing the printer via Casper Remote and it just stays there, if I manually run
/bin/launchctl load /Library/LaunchDaemons/com.mm2270.watchprinter.plist
via Terminal locally on the test Mac, that works to remove the printer.
But like I said, this is still a non-issue for what I need, because I won't be installing the printer via Casper to anybody outside of this department anyway. So as it stands it's still perfect for what I need.
Posted on 04-17-2015 02:45 PM
Yeah, that's pretty odd. I guess the way Casper Remote installs the printers, its not immediately triggering the LaunchDaemon. Maybe the WatchPath isn't actually seeing the item get dropped into the cups ppd directory for some reason. I don't know.
Since its a non issue as you stated, you probably don't need to do anything more with it.
OTOH, If that does become a problem at any point and you would like to solve that, one thing you could do is add a StartInterval entry into the LaunchDaemon, set it to some interval in seconds that isn't too frequent, like 120, 180, 240, etc. So every couple of minutes, the LaunchDaemon will activate, run the script and, if necessary, delete any printers that match the criteria. But it will also fire off by way of the WatchPath if someone manually adds the printer to their Mac. That would cover pretty much all scenarios I think.
Posted on 04-17-2015 02:57 PM
Ah, I get it. Yeah I'll do that if it becomes an issue. Thanks for all your help, I'm very happy with how it works.