Thoughts on NT Printing, Automatic Printer Share Generation
papowell at astart.com
papowell at astart.com
Sun Oct 8 00:03:06 GMT 2000
I downloaded the Samba_2_2 stuff, fired it up, read
the documentation, and fired up the NT printing stuff.
After a small (hey, no pain, no gain!) series of setbacks I set up
the necessary files to do driver setup. Ummm... I suggest you might
want to modify PRINTER_DRIVER2.txt:
[print$]
path = /usr/local/samba/printers
guest ok = yes
browseable = yes
read only = yes
write list = ntadmin,root,admin <--- grrr....
The write list specifies the users who will be allowed to <- correction here...
write to this directory. These users will be the ones allowed
to download driver files and other information to the samba
server.
The requirement for 'guest ok = yes' depends upon how your
site is configured. If users will be guaranteed to have
an account on the Samba host, then this is a non-issue.
<aside>
Ummm... OK, what are the issues? I kinda know I don't really want to
know, but I have this masochistic streak that begs to know the worst.
</aside>
MAIN TOPIC FOR PRESENTATION
Downloading drivers works for printers with defined shares,
but I discovered something REALLY nasty:
You have to do this for each individual printer.
Now before you start to say 'but you had to do this for all the
printers before', I have posted patches to the printing stuff
that allows you to specify IN THE PRINTCAP FILE the 'name' or 'key'
to be used for print driver lookup.
(I have also posted patches to the documentation as well, that describes
this, as well as a version of testprns that tests it, as well as a
modified version of smbprint that does NOT put the passwords onto
the command line, and warnings about the problems of duplicate
print files going into the print spool queue, but I digress...)
As the author/maintainer of the LPRng print spooler (and a couple
of other printing things), I have a vested interest in making
Samba and LPRng interface well. One of the things that is necessary
IMNSHO (In My Not So Humble Opinion) is a way to set up print shares
with the MINIMUM of effort by system administrators.
AND I DO NOT WANT TO CHANGE SAMBA ANY MORE THAN IS NECESSARY!!!
(Don't Fix What Is Not Broken Or You Maintain It Forever.)
So I spent a fair time staring/reading/admiring the Samba code that has been
added to the SAMBA_2_2 tree - this stuff is VERY clever, and I congratulate
the authors. Better them than me... the NT printing stuff looks HORRIBLE!
Here is the problem as I see it from an administration side:
You have your unix print spooling system. You set up a bunch
of print spool queues, and now you want to make them available
to Microsoft^H^Hother OS users, via Samba printer shares.
You (the system administrator) want to do this with the LEAST
amount of effort.
Here is currently what I am recommending to SysAdmins for this:
a) You either create a printcap format file for samba, or use
my patches (hint hint) and use:
printcap = /etc/printcap
printcap = |/bin/cat printcap
OR:
printcap = |/usr/local/samba/lib/getprinterinfo
#!/bin/sh
# printcap = |/usr/local/samba/lib/getprinterinfo
# use the following for older BSD print spoolers
/usr/bin/lpq -s | /bin/sed -e 's/@.*/:/'
# use the following for system V
# /usr/bin/lpstat -s | /bin/sed -n -e 's/:.*/:/' 's/system for //p'
OR if you are using LPRng:
printcap = |/usr/bin/lpc client
Now this will cause Samba to automatically generate the 'shares' for the
printers.
b) But this does not solve the problem of 'drivers' and downloading. I
fixed this by doing the following:
I assume that each printcap entry has the format (after you do the
line continution processing):
pr|alias1|alias2| .... :sd=/...:driver=Apple LaserWriter:cm=Comment...:...
The :driver=...: value is used as the value of the 'printer driver' field
in the configuration. The :cm=Comment...: field is used for the comment
information.
The patches to do this were REALLY small... Like 30 lines to params/loadconf.c
I think it was.
c) The existing 'print driver support' requires the samba administrator to
a) find the driver files and download them to a [PRINTER$] share
b) put a line in the 'print driver file' that had the necessary
information to allow W95 systems to download a driver. Each line
in printers.def had the format:
<Long Printer Name>\
:<Driver File Name>\
:<Data File Name>\
:<Help File Name>\
:<Language Monitor Name>\
:<Default Data Type>\
:<Comma Separated list of Files>
Example:
Apple Laserwriter I:.....
(you really really do not want to see the rest of the line.
Believe me.)
This resulted in the following smb.conf file:
[global]
# set defaults
printer driver file=/usr/local/samba/lib/printers.def
# %h will expand to the Samba Server name
printer driver location=\\%h\PRINTER$
[PRINTER$]
path=/usr/local/samba/printer
public=yes
writable=no
browsable=yes
# set default if you want
printer driver = HP LaserJet 4
[printers]
printcap = |/usr/local/samba/lib/getprinterinfo
And a printcap entry such as:
lp1:cm=Apple Printer in Room 1:driver=Apple LaserWriter
Now your windows 95 systems would do their magic, be handed
the information in the printers.def file, download the driver
files, and there would be singing and dancing in the corridors
and the sysadmins would get fat bonuses. But I digress.
<aside>
The 'Long Printer Name' does not need to be the original one used by
the installation procedure. You can play games here to prevent a known
good set of drivers from being overwritten by the &*())(*& user who
decides to load 'the latest driver' which does not work. Sigh...
</aside>
e) Now, I just know that you are wondering where this is going, and what
it has to do with NT printing. The answer is quite simple:
It is TRIVIAL to add printers with the same drivers to your system
and it does not require administering the Samba server.
You just add them to your printcap:
lp1:cm=Apple Printer in Room 1:driver=Apple LaserWriter
lp2:cm=Apple Printer in Room 2:driver=Apple LaserWriter
And AUTOMATICALLY the right driver is assigned to the right queue.
<aside>
Ummm... You may need to have Samba reread the configuration
file... so I guess there is SOME effort... Sigh...
</aside>
f) I have looked at the code in SAMBA_2_2, and it is really clever the
way that it does printer driver installation.
In order to add the same functionality using the printcap to
specify the driver for NT printing, the following might be
done. (There are alternatives, and I hope that somebody finds
a better one or a better way).
1. When you install an NT printer + Driver, the driver installation
and copy process should generate a 'lookup cookie' that is used to
identify the driver for this FAMILY of printers.
I recommend that the cookies start with:
W32X86 ; "Windows NT x86"
WIN40 ; "Windows 95/98"
W32ALPHA ; "Windows NT Alpha_AXP"
W32MIPS ; "Windows NT R4000"
W32PPC ; "Windows NT PowerPC"
2. The 'print driver' field will now be a LIST of strings
identifying the driver:
printer driver = W32X86_For_NT_cookie,WIN40_For_95_98_cookie,Apple LaserWriter
3. At the start of the driver identification process, the printer driver
string is examined and the appropriate cookie is located for the
appropriate system. For example, if the user wants WIN32X86
compatible drivers, you would look up the cookie using code
like the following:
char *bingo;
if( (bingo = strstr( lp_printerdriver,"WIN32X86")) ){
if( !(end = strchr(bingo,',')) end = bingo + strlen(bingo);
len = end - bingo;
copy_substring( cookie, bingo, len );
/* now use cookie for your lookup */
}
4. Now you use the cookie to look up the driver information in the database.
Actually, you might need a 'cookie' to 'really what it wants' lookup table,
but you get the idea. I hope.
5. If you do not find the magic cookie, then you use the code already there -
look for the installed driver, and then drop down to the code that
looks in the printers.def file. Ummm... OK you will have to do the
following instead of just a simple lookup, but that is not really
too difficult:
found = FALSE;
for( bingo = lp_printerdriver; !found && bingo && *bingo ; bingo = end ){
if( !(end = strchr(bingo,',')) end = bingo + strlen(bingo);
c = *end;
found = lookup driver info in printers.def using bingo;
*end = c;
if( c ) ++end;
}
Yeah, I know this is a pain, but it works...
f) There needs to be some way to get the 'cookie' information for the driver.
One way to do this is to have Samba maintain/create a file with the cookie
information and printer name. You also need a way to be able to set up
this information. For example, if you reinstall samba, then I gather
that all of the data in the TLB disappears. So you want to be able to
set it up in such a way that the same cookie references the same information.
Patrick Powell Astart Technologies,
papowell at astart.com 9475 Chesapeake Drive, Suite D,
Network and System San Diego, CA 92123
Consulting 858-874-6543 FAX 858-279-8424
LPRng - Print Spooler (http://www.astart.com)
More information about the samba-technical
mailing list