Of course, you can run all the commands that are embedded into the cupsaddsmb convenience utility yourself, one by one, and hereby upload and prepare the driver files for future client downloads.
Prepare Samba (A CUPS print queue with the name of the printer should be there. We are providing the driver now).
Copy all files to [print$] .
Run rpcclient adddriver (for each client architecture you want to support).
Run rpcclient setdriver .
We are going to do this now. First, read the man page on rpcclient to get a first idea. Look at all the printing related subcommands. enumprinters , enumdrivers , enumports , adddriver , setdriver are among the most interesting ones. rpcclient implements an important part of the MS-RPC protocol. You can use it to query (and command) a Windows NT (or 200x/XP) PC, too. MS-RPC is used by Windows clients , among other things, to benefit from the Point'n'Print features. Samba can now mimic this as well.
18.11.1 A Check of the rpcclient man Page
First let's check the rpcclient man page. Here are two relevant passages:
adddriver <arch> <config> Execute an AddPrinterDriver() RPC to install the printer driver information on the server. The driver files should already exist in the directory returned by getdriverdir . Possible values for arch are the same as those for the getdriverdir command. The config parameter is defined as follows :
Long Printer Name:\ Driver File Name:\ Data File Name:\ Config File Name:\ Help File Name:\ Language Monitor Name:\ Default Data Type:\ Comma Separated list of Files
Any empty fields should be enter as the string " NULL ".
Samba does not need to support the concept of Print Monitors since these only apply to local printers whose driver can make use of a bi-directional link for communication. This field should be " NULL ". On a remote NT print server, the Print Monitor for a driver must already be installed prior to adding the driver or else the RPC will fail.
setdriver <printername> <drivername> Execute a SetPrinter() command to update the printer driver associated with an installed printer. The printer driver must already be correctly installed on the print server.
See also the enumprinters and enumdrivers commands for obtaining a list of installed printers and drivers.
18.11.2 Understanding the rpcclient man Page
The exact format isn't made too clear by the man page, since you have to deal with some parameters containing spaces. Here is a better description for it. We have line-broken the command and indicated the breaks with "\". Usually you would type the command in one line without the linebreaks:
adddriver "Architecture" \ "LongPrinterName:DriverFile:DataFile:ConfigFile:HelpFile:\ LanguageMonitorFile:DataType:ListOfFiles,Comma-separated"
What the man pages denote as a simple < config > keyword, in reality consists of eight colon -separated fields. The last field may take multiple (in some very insane cases, even 20 different additional) files. This might sound confusing at first. What the man pages names the " LongPrinterName " in reality should be called the " Driver Name ". You can name it anything you want, as long as you use this name later in the rpcclient ... setdriver command. For practical reasons, many name the driver the same as the printer.
It isn't simple at all. I hear you asking: " How do I know which files are " Driver File ", " Data File ", " Config File ", " Help File " and " Language Monitor File" in each case? " For an answer, you may want to have a look at how a Windows NT box with a shared printer presents the files to us. Remember, that this whole procedure has to be developed by the Samba team by overhearing the traffic caused by Windows computers on the wire. We may as well turn to a Windows box now and access it from a UNIX workstation. We will query it with rpcclient to see what it tells us and try to understand the man page more clearly that we've read just now.
18.11.3 Producing an Example by Querying a Windows Box
We could run rpcclient with a getdriver or a getprinter subcommand (in level 3 verbosity ) against it. Just sit down at a UNIX or Linux workstation with the Samba utilities installed, then type the following command:
root# rpcclient -U' user %secret' NT-SERVER -c 'getdriver printername 3'
From the result it should become clear which is which. Here is an example from my installation:
root# rpcclient -U'Danka%xxxx' W200xSERVER \ -c'getdriver "DANKA InfoStream Virtual Printer" 3' cmd = getdriver "DANKA InfoStream Virtual Printer" 3 [Windows NT x86] Printer Driver Info 3: Version:  Driver Name: [DANKA InfoStream] Architecture: [Windows NT x86] Driver Path: [C:\WINNT\System32\spool\DRIVERS\W32X86\2\PSCRIPT.DLL] Datafile: [C:\WINNT\System32\spool\DRIVERS\W32X86\2\INFOSTRM.PPD] Configfile: [C:\WINNT\System32\spool\DRIVERS\W32X86\2\PSCRPTUI.DLL] Helpfile: [C:\WINNT\System32\spool\DRIVERS\W32X86\2\PSCRIPT.HLP] Dependentfiles:  Dependentfiles:  Dependentfiles:  Dependentfiles:  Dependentfiles:  Dependentfiles:  Dependentfiles:  Monitorname:  Defaultdatatype: 
Some printer drivers list additional files under the label Dependentfiles and these would go into the last field ListOfFiles , Comma-separated . For the CUPS PostScript drivers, we do not need any (nor would we for the Adobe PostScript driver), therefore, the field will get a " NULL " entry.
18.11.4 Requirements for adddriver and setdriver to Succeed
>From the man page (and from the quoted output of cupsaddsmb above) it becomes clear that you need to have certain conditions in order to make the manual uploading and initializing of the driver files succeed. The two rpcclient subcommands ( adddriver and setdriver ) need to encounter the following preconditions to complete successfully:
You are connected as printer admin or root (this is not the " Printer Operators " group in NT, but the printer admin group as defined in the [global] section of smb.conf ).
Copy all required driver files to \\SAMBA\print$\w32x86 and \\SAMBA\print$\win40 as appropriate. They will end up in the " " respective " 2 " subdirectories later. For now, do not put them there, they'll be automatically used by the adddriver subcommand. (If you use smbclient to put the driver files into the share, note that you need to escape the " $ ": smbclient //sambaserver/print\$ -U root .)
The user you're connecting as must be able to write to the [print$] share and create subdirectories.
The printer you are going to setup for the Windows clients needs to be installed in CUPS already.
The CUPS printer must be known to Samba, otherwise the setdriver subcommand fails with an NT_STATUS_UNSUCCESSFUL error. To check if the printer is known by Samba, you may use the enumprinters subcommand to rpcclient . A long-standing bug prevented a proper update of the printer list until every smbd process had received a SIGHUP or was restarted. Remember this in case you've created the CUPS printer just recently and encounter problems: try restarting Samba.
18.11.5 Manual Driver Installation in 15 Steps
We are going to install a printer driver now by manually executing all required commands. As this may seem a rather complicated process at first, we go through the procedure step by step, explaining every single action item as it comes up.
M ANUAL D RIVER I NSTALLATION
Install the printer on CUPS .
root# lpadmin -p mysmbtstprn -v socket://10.160.51.131:9100 -E \ -P canonIR85.ppd
This installs a printer with the name mysmbtstprn to the CUPS system. The printer is accessed via a socket (a.k.a. JetDirect or Direct TCP/IP) connection. You need to be root for this step.
(Optional) Check if the printer is recognized by Samba .
root# rpcclient -Uroot%xxxx -c 'enumprinters' localhost \ grep -C2 mysmbtstprn flags:[0x800000] name:[\\kde-bitshop\mysmbtstprn] description:[\\kde-bitshop\mysmbtstprn,,mysmbtstprn] comment:[mysmbtstprn]
This should show the printer in the list. If not, stop and restart the Samba daemon (smbd), or send a HUP signal:
root# kill -HUP 'pidof smbd'
Check again. Troubleshoot and repeat until successful. Note the " empty " field between the two commas in the " description " line. The driver name would appear here if there was one already. You need to know root's Samba password (as set by the smbpasswd command) for this step and most of the following steps. Alternately, you can authenticate as one of the users from the " write list " as defined in smb.conf for [print$] .
(Optional) Check if Samba knows a driver for the printer .
root# rpcclient -Uroot%xxxx -c 'getprinter mysmbtstprn 2' localhost \ grep driver drivername: root# rpcclient -Uroot%xxxx -c 'getprinter mysmbtstprn 2' localhost \ grep -C4 driv servername :[\\kde-bitshop] printername:[\\kde-bitshop\mysmbtstprn] sharename:[mysmbtstprn] portname:[Samba Printer Port] drivername: comment:[mysmbtstprn] location: sepfile: printprocessor:[winprint] root# rpcclient -U root%xxxx -c 'getdriver mysmbtstprn' localhost result was WERR_UNKNOWN_PRINTER_DRIVER
None of the three commands shown above should show a driver. This step was done for the purpose of demonstrating this condition. An attempt to connect to the printer at this stage will prompt the message along the lines of: " The server does not have the required printer driver installed ."
Put all required driver files into Samba's [print$] .
root# smbclient //localhost/print\$ -U 'root%xxxx' \ -c 'cd W32X86; \ put /etc/cups/ppd/mysmbtstprn.ppd mysmbtstprn.PPD; \ put /usr/share/cups/drivers/cupsui.dll cupsui.dll; \ put /usr/share/cups/drivers/cupsdrvr.dll cupsdrvr.dll; \ put /usr/share/cups/drivers/cups.hlp cups.hlp'
(This command should be entered in one long single line. Line-breaks and the line-end indicated by "\" have been inserted for readability reasons.) This step is required for the next one to succeed. It makes the driver files physically present in the [print$] share. However, clients would still not be able to install them, because Samba does not yet treat them as driver files. A client asking for the driver would still be presented with a " not installed here " message.
Verify where the driver files are now .
root# ls -l /etc/samba/drivers/W32X86/ total 669 drwxr-sr-x 2 root ntadmin 532 May 25 23:08 2 drwxr-sr-x 2 root ntadmin 670 May 16 03:15 3 -rwxr--r-- 1 root ntadmin 14234 May 25 23:21 cups.hlp -rwxr--r-- 1 root ntadmin 278380 May 25 23:21 cupsdrvr.dll -rwxr--r-- 1 root ntadmin 215848 May 25 23:21 cupsui.dll -rwxr--r-- 1 root ntadmin 169458 May 25 23:21 mysmbtstprn.PPD
The driver files now are in the W32X86 architecture " root " of [print$] .
Tell Samba that these are driver files (adddriver) .
root# rpcclient -Uroot%xxxx -c 'adddriver "Windows NT x86" \ "mydrivername:cupsdrvr.dll:mysmbtstprn.PPD: \ cupsui.dll:cups.hlp:NULL:RAW:NULL" \ localhost Printer Driver mydrivername successfully installed.
You cannot repeat this step if it fails. It could fail even as a result of a simple typo. It will most likely have moved a part of the driver files into the " 2 " subdirectory. If this step fails, you need to go back to the fourth step and repeat it before you can try this one again. In this step, you need to choose a name for your driver. It is normally a good idea to use the same name as is used for the printer name; however, in big installations you may use this driver for a number of printers that obviously have different names, so the name of the driver is not fixed.
Verify where the driver files are now .
root# ls -l /etc/samba/drivers/W32X86/ total 1 drwxr-sr-x 2 root ntadmin 532 May 25 23:22 2 drwxr-sr-x 2 root ntadmin 670 May 16 03:15 3 root# ls -l /etc/samba/drivers/W32X86/2 total 5039 [....] -rwxr--r-- 1 root ntadmin 14234 May 25 23:21 cups.hlp -rwxr--r-- 1 root ntadmin 278380 May 13 13:53 cupsdrvr.dll -rwxr--r-- 1 root ntadmin 215848 May 13 13:53 cupsui.dll -rwxr--r-- 1 root ntadmin 169458 May 25 23:21 mysmbtstprn.PPD
Notice how step 6 also moved the driver files to the appropriate subdirectory. Compare this with the situation after step 5.
(Optional) Verify if Samba now recognizes the driver .
root# rpcclient -Uroot%xxxx -c 'enumdrivers 3' \ localhost grep -B2 -A5 mydrivername Printer Driver Info 3: Version:  Driver Name: [mydrivername] Architecture: [Windows NT x86] Driver Path: [\\kde-bitshop\print$\W32X86\2\cupsdrvr.dll] Datafile: [\\kde-bitshop\print$\W32X86\2\mysmbtstprn.PPD] Configfile: [\\kde-bitshop\print$\W32X86\2\cupsui.dll] Helpfile: [\\kde-bitshop\print$\W32X86\2\cups.hlp]
Remember, this command greps for the name you chose for the driver in step 6. This command must succeed before you can proceed.
Tell Samba which printer should use these driver files ( setdriver ).
root# rpcclient -Uroot%xxxx -c 'setdriver mysmbtstprn mydrivername' \ localhost Successfully set mysmbtstprn to driver mydrivername
Since you can bind any printername (print queue) to any driver, this is a convenient way to setup many queues that use the same driver. You do not need to repeat all the previous steps for the setdriver command to succeed. The only preconditions are: enumdrivers must find the driver and enumprinters must find the printer.
(Optional) Verify if Samba has recognized this association .
root# rpcclient -Uroot%xxxx -c 'getprinter mysmbtstprn 2' localhost \ grep driver drivername:[mydrivername] root# rpcclient -Uroot%xxxx -c 'getprinter mysmbtstprn 2' localhost \ grep -C4 driv servername:[\\kde-bitshop] printername:[\\kde-bitshop\mysmbtstprn] sharename:[mysmbtstprn] portname:[Done] drivername:[mydrivername] comment:[mysmbtstprn] location: sepfile: printprocessor:[winprint] root# rpcclient -U root%xxxx -c 'getdriver mysmbtstprn' localhost [Windows NT x86] Printer Driver Info 3: Version:  Driver Name: [mydrivername] Architecture: [Windows NT x86] Driver Path: [\\kde-bitshop\print$\W32X86\2\cupsdrvr.dll] Datafile: [\\kde-bitshop\print$\W32X86\2\mysmbtstprn.PPD] Configfile: [\\kde-bitshop\print$\W32X86\2\cupsui.dll] Helpfile: [\\kde-bitshop\print$\W32X86\2\cups.hlp] Monitorname:  Defaultdatatype: [RAW] Monitorname:  Defaultdatatype: [RAW] root# rpcclient -Uroot%xxxx -c 'enumprinters' localhost \ grep mysmbtstprn name:[\\kde-bitshop\mysmbtstprn] description:[\\kde-bitshop\mysmbtstprn,mydrivername,mysmbtstprn] comment:[mysmbtstprn]
Compare these results with the ones from steps 2 and 3. Every one of these commands show the driver is installed. Even the enumprinters command now lists the driver on the " description " line.
(Optional) Tickle the driver into a correct device mode . You certainly know how to install the driver on the client. In case you are not particularly familiar with Windows, here is a short recipe: Browse the Network Neighborhood, go to the Samba server, and look for the shares. You should see all shared Samba printers. Double-click on the one in question. The driver should get installed and the network connection set up. An alternate way is to open the Printers (and Faxes) folder, right-click on the printer in question and select Connect or Install . As a result, a new printer should have appeared in your client's local Printers (and Faxes) folder, named something like printersharename on Sambahostname . It is important that you execute this step as a Samba printer admin (as defined in smb.conf ). Here is another method to do this on Windows XP. It uses a command line, which you may type into the " DOS box " (type root's smbpassword when prompted):
C:\> runas /netonly /user:root "rundll32 printui.dll,PrintUIEntry \ /in /n \\sambaserver\mysmbtstprn"
Change any printer setting once (like changing portrait to landscape ), click on Apply ; change the setting back.
Install the printer on a client (Point'n'Print) .
C:\> rundll32 printui.dll,PrintUIEntry /in /n \\sambaserver\mysmbtstprn
If it does not work it could be a permission problem with the [print$] share.
(Optional) Print a test page .
C:\> rundll32 printui.dll,PrintUIEntry /p /n "\\sambaserver\mysmbtstprn"
Then hit [TAB] five times, [ENTER] twice, [TAB] once and [ENTER] again and march to the printer.
(Recommended) Study the test page . Hmmm.... just kidding! By now you know everything about printer installations and you do not need to read a word. Just put it in a frame and bolt it to the wall with the heading "MY FIRST RPCCLIENT-INSTALLED PRINTER" why not just throw it away!
(Obligatory) Enjoy. Jump. Celebrate your success .
root# echo "Cheeeeerioooooo! Success..." >> /var/log/samba/log.smbd
18.11.6 Troubleshooting Revisited
The setdriver command will fail, if in Samba's mind the queue is not already there. You had promising messages about the:
Printer Driver ABC successfully installed.
after the adddriver parts of the procedure? But you are also seeing a disappointing message like this one?
result was NT_STATUS_UNSUCCESSFUL
It is not good enough that you can see the queue in CUPS, using the lpstat -p ir85wm command. A bug in most recent versions of Samba prevents the proper update of the queuelist. The recognition of newly installed CUPS printers fails unless you restart Samba or send a HUP to all smbd processes. To verify if this is the reason why Samba does not execute the setdriver command successfully, check if Samba " sees " the printer:
root# rpcclient transmeta -N -U'root%xxxx' -c 'enumprinters 0'grep ir85wm printername:[ir85wm]
An alternate command could be this:
root# rpcclient transmeta -N -U'root%secret' -c 'getprinter ir85wm' cmd = getprinter ir85wm flags:[0x800000] name:[\\transmeta\ir85wm] description:[\\transmeta\ir85wm,ir85wm,DPD] comment:[CUPS PostScript-Treiber for Windows NT/200x/XP]
By the way, you can use these commands, plus a few more, of course, to install drivers on remote Windows NT print servers too!