Thoughts on NT Printing, Automatic Printer Share Generation

papowell at papowell at
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:

				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

	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.

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.


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.

(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

    printcap = |/usr/local/samba/lib/getprinterinfo

    #  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

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

   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>


       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:

          # set defaults
          printer driver file=/usr/local/samba/lib/printers.def
          # %h will expand to the Samba Server name
          printer driver location=\\%h\PRINTER$
          # set default if you want
          printer driver = HP LaserJet 4

          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.

    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...

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.

   Ummm... You may need to have Samba reread the configuration
   file... so I guess there is SOME effort...  Sigh...

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            9475 Chesapeake Drive, Suite D,
Network and System             San Diego, CA 92123
  Consulting                   858-874-6543 FAX 858-279-8424 
LPRng - Print Spooler (

More information about the samba-technical mailing list