Software: Apache/2.0.54 (Fedora). PHP/5.0.4 uname -a: Linux mina-info.me 2.6.17-1.2142_FC4smp #1 SMP Tue Jul 11 22:57:02 EDT 2006 i686 uid=48(apache) gid=48(apache) groups=48(apache) Safe-mode: OFF (not secure) /usr/bin/X11/./../../share/doc/samba-3.0.23a/htmldocs/../htmldocs/Samba3-Developers-Guide/ drwxr-xr-x |
Viewing file: Select action/file-type: Table of Contents The purpose of this document is to provide some insight into Samba's printing functionality and also to describe the semantics of certain features of Windows client printing.
Samba uses a table of function pointers to seven functions. The
function prototypes are defined in the
Currently there are only two printing back end implementations defined.
Samba provides periodic caching of the output from the "lpq command" for performance reasons. This cache time is configurable in seconds. Obviously the longer the cache time the less often smbd will be required to exec a copy of lpq. However, the accuracy of the print queue contents displayed to clients will be diminished as well. The list of currently opened print queue TDB's can be found be examining the list of tdb_print_db structures ( see print_db_head in printing.c ). A queue TDB is opened using the wrapper function printing.c:get_print_db_byname(). The function ensures that smbd does not open more than MAX_PRINT_DBS_OPEN in an effort to prevent a large print server from exhausting all available file descriptors. If the number of open queue TDB's exceeds the MAX_PRINT_DBS_OPEN limit, smbd falls back to a most recently used algorithm for maintaining a list of open TDB's. There are two ways in which a a print job can be entered into a print queue's TDB. The first is to submit the job from a Windows client which will insert the job information directly into the TDB. The second method is to have the print job picked up by executing the "lpq command". /* included from printing.h */ struct printjob { pid_t pid; /* which process launched the job */ int sysjob; /* the system (lp) job number */ int fd; /* file descriptor of open file if open */ time_t starttime; /* when the job started spooling */ int status; /* the status of this job */ size_t size; /* the size of the job so far */ int page_count; /* then number of pages so far */ BOOL spooled; /* has it been sent to the spooler yet? */ BOOL smbjob; /* set if the job is a SMB job */ fstring filename; /* the filename used to spool the file */ fstring jobname; /* the job name given to us by the client */ fstring user; /* the user who started the job */ fstring queuename; /* service number of printer for this job */ NT_DEVICEMODE *nt_devmode; }; The current manifestation of the printjob structure contains a field for the UNIX job id returned from the "lpq command" and a Windows job ID (32-bit bounded by PRINT_MAX_JOBID). When a print job is returned by the "lpq command" that does not match an existing job in the queue's TDB, a 32-bit job ID above the <*vance doesn't know what word is missing here*> is generating by adding UNIX_JOB_START to the id reported by lpq. In order to match a 32-bit Windows jobid onto a 16-bit lanman print job id, smbd uses an in memory TDB to match the former to a number appropriate for old lanman clients.
When updating a print queue, smbd will perform the following
steps ( refer to
Note that it is the contents of this TDB that is returned to Windows clients and not the actual listing from the "lpq command". The NT_DEVICEMODE stored as part of the printjob structure is used to store a pointer to a non-default DeviceMode associated with the print job. The pointer will be non-null when the client included a Device Mode in the OpenPrinterEx() call and subsequently submitted a job for printing on that same handle. If the client did not include a Device Mode in the OpenPrinterEx() request, the nt_devmode field is NULL and the job has the printer's device mode associated with it by default. Only non-default Device Mode are stored with print jobs in the print queue TDB. Otherwise, the Device Mode is obtained from the printer object when the client issues a GetJob(level == 2) request. When working with Windows NT+ clients, it is possible for a print server to use RPC to send asynchronous change notification events to clients for certain printer and print job attributes. This can be useful when the client needs to know that a new job has been added to the queue for a given printer or that the driver for a printer has been changed. Note that this is done entirely orthogonal to cache updates based on a new ChangeID for a printer object. The basic set of RPC's used to implement change notification are
One additional RPC is available to a server, but is never used by the Windows spooler service:
The opnum for all of these RPC's are defined in include/rpc_spoolss.h Windows NT print servers use a bizarre method of sending print notification event to clients. The process of registering a new change notification handle is as follows. The 'C' is for client and the 'S' is for server. All error conditions have been eliminated. C: Obtain handle to printer or to the printer server via the standard OpenPrinterEx() call. S: Respond with a valid handle to object C: Send a RFFPCN request with the previously obtained handle with either (a) set of flags for change events to monitor, or (b) a PRINTER_NOTIFY_OPTIONS structure containing the event information to monitor. The windows spooler has only been observed to use (b). S: The <* another missing word*> opens a new TCP session to the client (thus requiring all print clients to be CIFS servers as well) and sends a ReplyOpenPrinter() request to the client. C: The client responds with a printer handle that can be used to send event notification messages. S: The server replies success to the RFFPCN request. C: The windows spooler follows the RFFPCN with a RFNPCN request to fetch the current values of all monitored attributes. S: The server replies with an array SPOOL_NOTIFY_INFO_DATA structures (contained in a SPOOL_NOTIFY_INFO structure). C: If the change notification handle is ever released by the client via a FCPCN request, the server sends a ReplyClosePrinter() request back to the client first. However a request of this nature from the client is often an indication that the previous notification event was not marshalled correctly by the server or a piece of data was wrong. S: The server closes the internal change notification handle (POLICY_HND) and does not send any further change notification events to the client for that printer or job. The current list of notification events supported by Samba can be found by examining the internal tables in srv_spoolss_nt.c
When an event occurs that could be monitored, smbd sends a message to itself about the change. The list of events to be transmitted are queued by the smbd process sending the message to prevent an overload of TDB usage and the internal message is sent during smbd's idle loop (refer to printing/notify.c and the functions send_spoolss_notify2_msg() and print_notify_send_messages() ). The decision of whether or not the change is to be sent to connected clients is made by the routine which actually sends the notification. ( refer to srv_spoolss_nt.c:recieve_notify2_message() ). Because it possible to receive a listing of multiple changes for multiple printers, the notification events must be split into categories by the printer name. This makes it possible to group multiple change events to be sent in a single RPC according to the printer handle obtained via a ReplyOpenPrinter(). The actual change notification is performed using the RRPCN request RPC. This packet contains
A
The
|
:: Command execute :: | |
--[ c99shell v. 1.0 pre-release build #16 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0039 ]-- |