1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.

This commit is contained in:
cvs2svn Import User 0001-01-01 00:00:00 +00:00
commit eb5ce70e2f
9 changed files with 9723 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,393 @@
<chapter id="printing">
<chapterinfo>
<author>
<firstname>Gerald</firstname><surname>Carter</surname>
</author>
<pubdate>October 2002</pubdate>
</chapterinfo>
<title>Samba Printing Internals</title>
<sect1>
<title>Abstract</title>
<para>
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.
</para>
</sect1>
<sect1>
<title>
Printing Interface to Various Back ends
</title>
<para>
Samba uses a table of function pointers to seven functions. The
function prototypes are defined in the <VarName>printif</VarName> structure declared
in <filename>printing.h</filename>.
</para>
<itemizedlist>
<listitem><para>retrieve the contents of a print queue</para></listitem>
<listitem><para>pause the print queue</para></listitem>
<listitem><para>resume a paused print queue</para></listitem>
<listitem><para>delete a job from the queue</para></listitem>
<listitem><para>pause a job in the print queue</para></listitem>
<listitem><para>result a paused print job in the queue</para></listitem>
<listitem><para>submit a job to the print queue</para></listitem>
</itemizedlist>
<para>
Currently there are only two printing back end implementations
defined.
</para>
<itemizedlist>
<listitem><para>a generic set of functions for working with standard UNIX
printing subsystems</para></listitem>
<listitem><para>a set of CUPS specific functions (this is only enabled if
the CUPS libraries were located at compile time).</para></listitem>
</itemizedlist>
</sect1>
<sect1>
<title>
Print Queue TDB's
</title>
<para>
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.
</para>
<para>
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.
</para>
<para>
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".
</para>
<para><programlisting>
/* 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;
};
</programlisting></para>
<para>
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 &lt;*vance doesn't know what word is missing here*&gt; is generating by adding UNIX_JOB_START to
the id reported by lpq.
</para>
<para>
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.
</para>
<para>
When updating a print queue, smbd will perform the following
steps ( refer to <filename>print.c:print_queue_update()</filename> ):
</para>
<orderedlist>
<listitem><para>Check to see if another smbd is currently in
the process of updating the queue contents by checking the pid
stored in <constant>LOCK/<replaceable>printer_name</replaceable></constant>.
If so, then do not update the TDB.</para></listitem>
<listitem><para>Lock the mutex entry in the TDB and store our own pid.
Check that this succeeded, else fail.</para></listitem>
<listitem><para>Store the updated time stamp for the new cache
listing</para></listitem>
<listitem><para>Retrieve the queue listing via "lpq command"</para></listitem>
<listitem><para><programlisting>
foreach job in the queue
{
if the job is a UNIX job, create a new entry;
if the job has a Windows based jobid, then
{
Lookup the record by the jobid;
if the lookup failed, then
treat it as a UNIX job;
else
update the job status only
}
}</programlisting></para></listitem>
<listitem><para>Delete any jobs in the TDB that are not
in the in the lpq listing</para></listitem>
<listitem><para>Store the print queue status in the TDB</para></listitem>
<listitem><para>update the cache time stamp again</para></listitem>
</orderedlist>
<para>
Note that it is the contents of this TDB that is returned to Windows
clients and not the actual listing from the "lpq command".
</para>
<para>
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.
</para>
<para>
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.
</para>
</sect1>
<sect1>
<title>
ChangeID & Client Caching of Printer Information
</title>
<para>
[To be filled in later]
</para>
</sect1>
<sect1>
<title>
Windows NT/2K Printer Change Notify
</title>
<para>
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.
</para>
<para>
The basic set of RPC's used to implement change notification are
</para>
<itemizedlist>
<listitem><para>RemoteFindFirstPrinterChangeNotifyEx ( RFFPCN )</para></listitem>
<listitem><para>RemoteFindNextPrinterChangeNotifyEx ( RFNPCN )</para></listitem>
<listitem><para>FindClosePrinterChangeNotify( FCPCN )</para></listitem>
<listitem><para>ReplyOpenPrinter</para></listitem>
<listitem><para>ReplyClosePrinter</para></listitem>
<listitem><para>RouteRefreshPrinterChangeNotify ( RRPCN )</para></listitem>
</itemizedlist>
<para>
One additional RPC is available to a server, but is never used by the
Windows spooler service:
</para>
<itemizedlist>
<listitem><para>RouteReplyPrinter()</para></listitem>
</itemizedlist>
<para>
The opnum for all of these RPC's are defined in include/rpc_spoolss.h
</para>
<para>
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.
</para>
<para><programlisting>
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 &lt;* another missing word*&gt; 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.
</programlisting></para>
<para>
The current list of notification events supported by Samba can be
found by examining the internal tables in srv_spoolss_nt.c
</para>
<itemizedlist>
<listitem><para>printer_notify_table[]</para></listitem>
<listitem><para>job_notify_table[]</para></listitem>
</itemizedlist>
<para>
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() ).
</para>
<para>
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() ).
</para>
<para>
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().
</para>
<para>
The actual change notification is performed using the RRPCN request
RPC. This packet contains
</para>
<itemizedlist>
<listitem><para>the printer handle registered with the
client's spooler on which the change occurred</para></listitem>
<listitem><para>The change_low value which was sent as part
of the last RFNPCN request from the client</para></listitem>
<listitem><para>The SPOOL_NOTIFY_INFO container with the event
information</para></listitem>
</itemizedlist>
<para>
A <VarName>SPOOL_NOTIFY_INFO</VarName> contains:
</para>
<itemizedlist>
<listitem><para>the version and flags field are predefined
and should not be changed</para></listitem>
<listitem><para>The count field is the number of entries
in the SPOOL_NOTIFY_INFO_DATA array</para></listitem>
</itemizedlist>
<para>
The <VarName>SPOOL_NOTIFY_INFO_DATA</VarName> entries contain:
</para>
<itemizedlist>
<listitem><para>The type defines whether or not this event
is for a printer or a print job</para></listitem>
<listitem><para>The field is the flag identifying the event</para></listitem>
<listitem><para>the notify_data union contains the new valuie of the
attribute</para></listitem>
<listitem><para>The enc_type defines the size of the structure for marshalling
and unmarshalling</para></listitem>
<listitem><para>(a) the id must be 0 for a printer event on a printer handle.
(b) the id must be the job id for an event on a printer job
(c) the id must be the matching number of the printer index used
in the response packet to the RFNPCN when using a print server
handle for notification. Samba currently uses the snum of
the printer for this which can break if the list of services
has been modified since the notification handle was registered.</para></listitem>
<listitem><para>The size is either (a) the string length in UNICODE for strings,
(b) the size in bytes of the security descriptor, or (c) 0 for
data values.</para></listitem>
</itemizedlist>
</sect1>
</chapter>

View File

@ -0,0 +1,79 @@
<chapter id="wins">
<chapterinfo>
<author>
<firstname>Gerald</firstname><surname>Carter</surname>
</author>
<pubdate>October 2002</pubdate>
</chapterinfo>
<title>Samba WINS Internals</title>
<sect1>
<title>WINS Failover</title>
<para>
The current Samba codebase possesses the capability to use groups of WINS
servers that share a common namespace for NetBIOS name registration and
resolution. The formal parameter syntax is
</para>
<para><programlisting>
WINS_SERVER_PARAM = SERVER [ SEPARATOR SERVER_LIST ]
WINS_SERVER_PARAM = &quot;wins server&quot;
SERVER = ADDR[:TAG]
ADDR = ip_addr | fqdn
TAG = string
SEPARATOR = comma | \s+
SERVER_LIST = SERVER [ SEPARATOR SERVER_LIST ]
</programlisting></para>
<para>
A simple example of a valid wins server setting is
</para>
<para><programlisting>
[global]
wins server = 192.168.1.2 192.168.1.3
</programlisting></para>
<para>
In the event that no TAG is defined in for a SERVER in the list, smbd assigns a default
TAG of &quot;*&quot;. A TAG is used to group servers of a shared NetBIOS namespace together. Upon
startup, nmbd will attempt to register the netbios name value with one server in each
tagged group.
</para>
<para>
An example using tags to group WINS servers together is show here. Note that the use of
interface names in the tags is only by convention and is not a technical requirement.
</para>
<para><programlisting>
[global]
wins server = 192.168.1.2:eth0 192.168.1.3:eth0 192.168.2.2:eth1
</programlisting></para>
<para>
Using this configuration, nmbd would attempt to register the server's NetBIOS name
with one WINS server in each group. Because the &quot;eth0&quot; group has two servers, the
second server would only be used when a registration (or resolution) request to
the first server in that group timed out.
</para>
<para>
NetBIOS name resolution follows a similar pattern as name registration. When resolving
a NetBIOS name via WINS, smbd and other Samba programs will attempt to query a single WINS
server in a tagged group until either a positive response is obtained at least once or
until a server from every tagged group has responded negatively to the name query request.
If a timeout occurs when querying a specific WINS server, that server is marked as down to
prevent further timeouts and the next server in the WINS group is contacted. Once marked as
dead, Samba will not attempt to contact that server for name registration/resolution queries
for a period of 10 minutes.
</para>
</sect1>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,589 @@
Date: Sun, 22 Sep 2002 15:38:02 +0200
From: "Kurt Pfeifle" <kpfeifle@danka.de>
Reply-To: kpfeifle@danka.de
Organization: Danka Deutschland GmbH
To: samba@lists.samba.org
Subject: CUPS filtering mechanism explained, was: [cups raw mode, was Re: [Samba] unlink data file in cups_job_submit]
Paul Janzen wrote on Samba digest:
> Message: 7
> To: Gerald Carter <jerry@samba.org>
> Cc: samba@lists.samba.org
> From: Paul Janzen <pcj@samba.sez.to>
> Subject: cups raw mode, was Re: [Samba] unlink data file in cups_job_submit
> Date: 21 Sep 2002 12:09:23 -0700
>
>
> Gerald Carter <jerry@samba.org> writes:
>
> > Looks right to me [:-)] Applying it now. Thanks. I've been meaning to
> > track this one down.
>
>
> Thanks!
>
> While we are on the subject... [:-)]
>
> If I am using native printer drivers on Windows clients, I would like
> the "raw" option to get propagated to CUPS. Otherwise cups does not
> pass the data on to the printer.
Paul,
I see you know about what you call the "raw data passthrough feature".
I guess you mean the lines in "/etc/cups/mime.types" and
"/etc/cups/mime.convs" which need to be uncommented to allow "raw"
printing ?
Here is some clarification (likely not very useful for you, but
possibly for some other readers of the Samba list):
### If you have "printing = cups" and "printcap = cups" enabled,
--- everything is handled by Samba accessing the CUPS API. (And any
"print command" directive in Samba will be ignored.) If the CUPS
API is not available (because Samba might not be compiled against
libcups), it automatically maps to the "System V" command set, with
"-oraw" enabled automatically.
> (If I enable cups's application/
> octet-stream raw-data passthrough feature, both cupsomatic and the
> Windows driver add PJL headers and footers, which is not what I want
> either.)
### According to my experience, cupsomatic on the Samba/CUPS server
--- does *not* add any features if a file is really printed "raw".
However, if you have loaded the driver for the Windows client
from the CUPS server, using the "cupsaddsmb" utility, and if this
driver is one using a "Foomatic" PPD, the PJL header in question is
already added on the Windows client, at the time when the driver
initially generated the PostScript data -- and CUPS in true "-oraw"
manner doesn't remove this PJL header and passes the file "as is"
to its printer communication backend.
NOTE, please, that the editing in the "mime.convs" and the
----- "mime.types" file does not *enforce* "raw" printing, it
only *allows* it. Any file arriving from Windows is
"auto-typed" by CUPS, which might consecutively lead to its
treatment by various filters automatically (depending on the
actual outcome of the auto-typing and the configuration of the
printqueue in question):
--> Files generated by PCL drivers and destined to PCL
printers get auto-typed "application/octet-stream"
and are indeed printed "raw". Also, unknown file
types are getting tagged as "application/octet-stream".
--> Files generated by a PostScript driver (and destined
for any target printer type) are auto-typed. Depending
on the driver, the discovered MIME type may be
* application/postscript or
* application/vnd.cups-postscript
"application/postscript" goes first thru the "pstops" filter
(where also the page counting and accounting takes place
currently), and the outcome will be of MIME type
"application/vnd.cups-postscript". The pstopsfilter reads and
uses information from the PPD and inserts user-provided options
into the PostScript file. As a consequence, the filtered file
will possibly have the PJL header you don't want.
"application/postscript" will be all files with a ".ps", ".ai",
".eps" suffix or which have as their first character string one
of "%!" or "<04>%".
"application/vnd.cups-postscript" will be those files which do both,
first...
...carry a string "LANGUAGE=POSTSCRIPT" (or similar variations
with different capitalization) amongst the first 512 bytes,
*plus*...
...contain the "PJL super escape code" amongst the first 128
bytes ("<1B>%-12345X"). Very likely, most PostScript files
generated on Windows using a CUPS- or other PPD, will have
to be auto-typed as "vnd.cups-postscript".
Probably a file produced with a "Generic PostScript driver"
will be just "application/postscript" (have not checked).
Once the file is in "application/vnd.cups-postscript" format,
either "pstoraster" or "cupsomatic" will take over (depending
on the printer configuration, as determined by the PPD in use).
NOTE: a printer queue with *no* PPD associated to it is a "raw"
----- printer and all files will go directly there as received
by the spooler; the exeption are file types
"application/octet-stream" which need the mentioned "passthrough
feature" enabled. "Raw" queues don't do any filtering at all, they
hand the file directly to the CUPS backend. This backend is
responsible for the sending of the data to the device (as visible
in the "device URI" notation as lpd://, socket://, smb://, ipp://,
http://, parallel:/, serial:/, usb:/ etc.)
NOTE, please, also the following fact: "cupsomatic"/Foomatic are
----- *not* native CUPS drivers and they don't ship with CUPS.
They are a Third Party add-on, developed at Linuxprinting.org.
As such, they are a brilliant hack to make all models (driven by
Ghostscript drivers/filters in traditional spoolers) also work via
CUPS, with the same (good or bad!) quality as in these other
spoolers. "cupsomatic" is only a vehicle to execute a ghostscript
commandline at that stage in the CUPS filtering chain, where
"normally" the native CUPS "pstoraster" filter would kick in.
cupsomatic by-passes pstoraster, "kidnaps" the printfile from CUPS
away and re-directs it to go through Ghostscipt. CUPS accepts this,
because the associated CUPS-O-Matic-/Foomatic-PPD carries a line
reading
*cupsFilter: "application/vnd.cups-postscript 0 cupsomatic"
This line persuades CUPS to hand the file to cupsomatic, once it
has successfully converted it to the MIME type
"application/vnd.cups-postscript". This conversion will not
happen for Jobs arriving from Windows which are autotyped
"application/octet-stream", with the according changes in
"/etc/cups/mime.types" in place.
See small drawings at the end...
I am not a programmer, so please correct me if I am wrong.
> With traditional lpr, you can just add "-oraw" to the "print command"
> line in smb.conf. With cups, you don't have that alternative.
You *do* have it, I think.
But you need to disable the settings "printing = cups" and "printcap =
= cups" and use "printing = bsd" and "printcap = /etc/printcap"
instead. [Additionally, you will probably have to enable and configure
the CUPS mini-LPD daemon ("cups-lpd") run from inetd... but I have not
checked, so take this item with a grain of salt and a proper dose of
caution, please.]
> The result is that to support both unix printing and native-driver
> Windows printing from CUPS, you have to have two logical printers per
> physical printer: one ("cooked") for Unix clients and one ("raw") for
> Samba to use.
Yes, that is one current workaround, if you don't want the auto-typing
of CUPS influencing Samba/Windows client PostScript jobs.
CUPS is widely configurable and flexible, even regarding its filtering
mechanism. Another workaround in some situations would be to have
lines in "/etc/cups/mime.types" saying
application/postscript application/vnd.cups-raw 0 -
application/vnd.cups-postscript application/vnd.cups-raw 0 -
This would prevent all Postscript files to be filtered (or rather, they
will go thru the virtual "nullfilter" denoted with "-". (This could only
be useful for PS printers, or if you want to print PS code on non-PS
printers ;-)
A single line of
*/* application/vnd.cups-raw 0 -
would effectively send *all* files towards the backend immediately
(good luck!)
Last, you could have the following (without the need for a Samba
patch):
application/vnd.cups-postscript application/vnd.cups-raw 0 my_PJL_stripping_filter
You'd need to write a "my_PJL_stripping_filter" (could be a shellscript)
which parses the PostScript and removes the undesired PJL. This would
need to conform to CUPS filter design (mainly, receive and pass the
parameters printername, job-id, username, jobtitle, copies, printoptions
and possibly the filename). It would just go as world executably into
"/usr/lib/cups/filters/" and work from there, called by cups if it
encounters a MIME type "application/vnd.cups-postscript"
> The attached patch allows you to specify an option string for cups
> printers in smb.conf.
I think your patch is in any case very useful (if it works as
advertised ;-). It is the most generic, simple and flexible
approach to complement CUPS.
> So, if you want to use native Windows drivers,
> all you need is
>
> cups printer options = raw
>
> in smb.conf. You can add any other options that cups and the printer
> understand.
Now this last sentence makes me very curious. Do you mean you can add
*multiple* options to this directive? Which syntax would be required
for this ? (Some CUPS options are specified by an "-o option=value"
pair on the commandline, some are single values, like the "-o raw"
one...)
I am thinking on one specific usage now:
-----------------------------------------------------------------------
-> passing any available IPP job attribute to the printer / the spooler
-----------------------------------------------------------------------
For example, CUPS can handle "-o job-hold-until=indefinite". This
keeps the job in the queue "on hold". It will only be printed upon
manual release by the printer operator. This is a requirement in
many "central reproduction departments", where a few operators
manage the jobs of hundreds of users on some big machine, where no
user is allowed to have direct access. (The operators often need to
load the proper paper type before running the 10.000 page job
requested by marketing for the mailing, etc.).
A lot more useful applications come to mind, if I could pass
"any other options that cups and the printer understand" via
the smb.conf directive!!
Thanks a lot!
Cheers,
Kurt
P.S.: List, please give me some feedback, if you think this type of
explanation could be useful in the Samba HOWTO Collection. In
that case, I'll try to write it up in a nicer form.
#########################################################################
#
# CUPS in and of itself has this (general) filter chain (CAPITAL
# letters are FILE-FORMATS or MIME types, other are filters (this is
# true for pre-1.1.15 of pre-4.3 versions of CUPS and ESP PrintPro):
#
# <SOMETHNG>-FILEFORMAT
# |
# |
# V
# <something>tops
# |
# |
# V
# APPLICATION/POSTSCRIPT
# |
# |
# V
# pstops
# |
# |
# V
# APPLICATION/VND.CUPS-POSTSCRIPT
# |
# |
# V
# pstoraster # as shipped with CUPS, independent from any Ghostscipt
# | # installation on the system
# | (= "postscipt interpreter")
# |
# V
# APPLICATION/VND.CUPS-RASTER
# |
# |
# V
# rasterto<something> (f.e. Gimp-Print filters may be plugged in here)
# | (= "raster driver")
# |
# V
# SOMETHING-DEVICE-SPECIFIC
# |
# |
# V
# backend
#
#
# ESP PrintPro has some enhanced "rasterto<something>" filters as compared to
# CUPS, and also a somewhat improved "pstoraster" filter.
#
# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
#
#
#########################################################################
#
# This is how "cupsomatic" comes into play:
# =========================================
#
# <SOMETHNG>-FILEFORMAT
# |
# |
# V
# <something>tops
# |
# |
# V
# APPLICATION/POSTSCRIPT
# |
# |
# V
# pstops
# |
# |
# V
# APPLICATION/VND.CUPS-POSTSCRIPT ----------------+
# | |
# | V
# V cupsomatic
# pstoraster (constructs complicated
# | (= "postscipt interpreter") Ghostscript commandline
# | to let the file be
# V processed by a
# APPLICATION/VND.CUPS-RASTER "-sDEVICE=<s.th.>"
# | call...)
# | |
# V |
# rasterto<something> V
# | (= "raster driver") +-------------------------+
# | | Ghostscript at work.... |
# V | |
# SOMETHING-DEVICE-SPECIFIC *-------------------------+
# | |
# | |
# V |
# backend <------------------------------------+
# |
# |
# V
# THE PRINTER
#
#
#
# Note, that cupsomatic "kidnaps" the printfile after the
# "APPLICATION/VND.CUPS-POSTSCRPT" stage and deviates it through
# the CUPS-external, systemwide Ghostscript installation, bypassing the
# "pstoraster" filter (therefor also bypassing the CUPS-raster-drivers
# "rasterto<something>", and hands the rasterized file directly to the CUPS
# backend...
#
# cupsomatic is not made by the CUPS developers. It is an independent
# contribution to printing development, made by people from
# Linuxprinting.org. (see also http://www.cups.org/cups-help.html)
#
# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
#
#
#########################################################################
#
# And this is how it works for ESP PrintPro from 4.3:
# ===================================================
#
# <SOMETHNG>-FILEFORMAT
# |
# |
# V
# <something>tops
# |
# |
# V
# APPLICATION/POSTSCRIPT
# |
# |
# V
# pstops
# |
# |
# V
# APPLICATION/VND.CUPS-POSTSCRIPT
# |
# |
# V
# gsrip
# | (= "postscipt interpreter")
# |
# V
# APPLICATION/VND.CUPS-RASTER
# |
# |
# V
# rasterto<something> (f.e. Gimp-Print filters may be plugged in here)
# | (= "raster driver")
# |
# V
# SOMETHING-DEVICE-SPECIFIC
# |
# |
# V
# backend
#
# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
#
#
#########################################################################
#
# This is how "cupsomatic" would come into play with ESP PrintPro:
# ================================================================
#
#
# <SOMETHNG>-FILEFORMAT
# |
# |
# V
# <something>tops
# |
# |
# V
# APPLICATION/POSTSCRIPT
# |
# |
# V
# pstops
# |
# |
# V
# APPLICATION/VND.CUPS-POSTSCRIPT ----------------+
# | |
# | V
# V cupsomatic
# gsrip (constructs complicated
# | (= "postscipt interpreter") Ghostscript commandline
# | to let the file be
# V processed by a
# APPLICATION/VND.CUPS-RASTER "-sDEVICE=<s.th.>"
# | call...)
# | |
# V |
# rasterto<something> V
# | (= "raster driver") +-------------------------+
# | | Ghostscript at work.... |
# V | |
# SOMETHING-DEVICE-SPECIFIC *-------------------------+
# | |
# | |
# V |
# backend <------------------------------------+
# |
# |
# V
# THE PRINTER
#
# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
#
#########################################################################
#
# And this is how it works for CUPS from 1.1.15:
# ==============================================
#
# <SOMETHNG>-FILEFORMAT
# |
# |
# V
# <something>tops
# |
# |
# V
# APPLICATION/POSTSCRIPT
# |
# |
# V
# pstops
# |
# |
# V
# APPLICATION/VND.CUPS-POSTSCRIPT-----+
# |
# +------------------v------------------------------+
# | Ghostscript |
# | at work... |
# | (with |
# | "-sDEVICE=cups") |
# | |
# | (= "postscipt interpreter") |
# | |
# +------------------v------------------------------+
# |
# |
# APPLICATION/VND.CUPS-RASTER <-------+
# |
# |
# V
# rasterto<something>
# | (= "raster driver")
# |
# V
# SOMETHING-DEVICE-SPECIFIC
# |
# |
# V
# backend
#
#
# NOTE: since version 1.1.15 CUPS "outsourced" the pstoraster process to
# Ghostscript. GNU Ghostscript needs to be patched to handle the
# CUPS requirement; ESP Ghostscript has this builtin. In any case,
# "gs -h" needs to show up a "cups" device. pstoraster is now a
# calling an appropriate "gs -sDEVICE=cups..." commandline to do
# the job. It will output "application/vnd.cup-raster", which will
# be finally processed by a CUPS raster driver "rasterto<something>"
# Note the difference to "cupsomatic", which will *not* output
# CUPS-raster, but a final version of the printfile, ready to be
# sent to the printer. cupsomatic also doesn't use the "cups"
# devicemode in Ghostscript, but one of the classical devicemodes....
#
# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
#
#########################################################################
#
# And this is how it works for CUPS from 1.1.15, with cupsomatic included:
# ========================================================================
#
# <SOMETHNG>-FILEFORMAT
# |
# |
# V
# <something>tops
# |
# |
# V
# APPLICATION/POSTSCRIPT
# |
# |
# V
# pstops
# |
# |
# V
# APPLICATION/VND.CUPS-POSTSCRIPT-----+
# |
# +------------------v------------------------------+
# | Ghostscript . Ghostscript at work.... |
# | at work... . (with "-sDEVICE= |
# | (with . <s.th.>" |
# | "-sDEVICE=cups") . |
# | . |
# | (CUPS standard) . (cupsomatic) |
# | . |
# | (= "postscript interpreter") |
# | . |
# +------------------v--------------v---------------+
# | |
# | |
# APPLICATION/VND.CUPS-RASTER <-------+ |
# | |
# | |
# V |
# rasterto<something> |
# | (= "raster driver") |
# | |
# V |
# SOMETHING-DEVICE-SPECIFIC <------------------------+
# |
# |
# V
# backend
#
#
# NOTE: Gimp-Print and some other 3rd-Party-Filters (like TurboPrint) to
# CUPS and ESP PrintPro plug-in where rasterto<something> is noted.
#
##########################################################################
I hope this helps more people understand how CUPS works and how they
can possibly tweak it to their needs.

View File

@ -0,0 +1,39 @@
This file contains a listing of various other VFS modules that
have been posted but don't currently reside in the Samba CVS
tree for one reason ot another (e.g. it is easy for the maintainer
to have his or her own CVS tree).
No statemets about the stability or functionality any module
should be implied due to its presence here.
------------------------------------------------------------
Date: Sat, 28 Sep 2002 23:41:31 -0500
From: Eric Lorimer <elorimer@css.tayloru.edu>
To: samba-technical@lists.samba.org
Subject: DatabaseFS VFS module
Hello,
I have created a VFS module which implements a fairly complete read-only
filesystem. It presents information from a database as a filesystem in
a modular and generic way to allow different databases to be used
(originally designed for organizing MP3s under directories such as
"Artists," "Song Keywords," etc... I have since applied it to a student
roster database very easily). The directory structure is stored in the
database itself and the module makes no assumptions about the database
structure beyond the table it requires to run. You can find it at:
http://www.css.tayloru.edu/~elorimer/databasefs/index.php
Any feedback would be appreciated: comments, suggestions, patches,
etc... If nothing else, hopefully it might prove useful for someone
else who wishes to create a virtual filesystem.
Thanks for the great product and keep up the good work.
- Eric Lorimer
------------------------------------------------------------

145
source/libads/ads_ldap.c Normal file
View File

@ -0,0 +1,145 @@
/*
Unix SMB/CIFS implementation.
Winbind ADS backend functions
Copyright (C) Andrew Tridgell 2001
Copyright (C) Andrew Bartlett 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#ifdef HAVE_LDAP
/* convert a single name to a sid in a domain */
NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
const char *name,
DOM_SID *sid,
enum SID_NAME_USE *type)
{
const char *attrs[] = {"objectSid", "sAMAccountType", NULL};
int count;
ADS_STATUS rc;
void *res = NULL;
char *exp;
uint32 t;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
name, name, ads->config.realm) == -1) {
DEBUG(1,("ads_name_to_sid: asprintf failed!\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
rc = ads_search_retry(ads, &res, exp, attrs);
free(exp);
if (!ADS_ERR_OK(rc)) {
DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
goto done;
}
count = ads_count_replies(ads, res);
if (count != 1) {
DEBUG(1,("name_to_sid: %s not found\n", name));
goto done;
}
if (!ads_pull_sid(ads, res, "objectSid", sid)) {
DEBUG(1,("No sid for %s !?\n", name));
goto done;
}
if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) {
DEBUG(1,("No sAMAccountType for %s !?\n", name));
goto done;
}
*type = ads_atype_map(t);
status = NT_STATUS_OK;
DEBUG(3,("ads name_to_sid mapped %s\n", name));
done:
if (res) ads_msgfree(ads, res);
return status;
}
/* convert a sid to a user or group name */
NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
TALLOC_CTX *mem_ctx,
const DOM_SID *sid,
char **name,
enum SID_NAME_USE *type)
{
const char *attrs[] = {"userPrincipalName",
"sAMAccountName",
"sAMAccountType", NULL};
ADS_STATUS rc;
void *msg = NULL;
char *exp = NULL;
char *sidstr = NULL;
uint32 atype;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
if (!(sidstr = sid_binstring(sid))) {
DEBUG(1,("ads_sid_to_name: sid_binstring failed!\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
if (asprintf(&exp, "(objectSid=%s)", sidstr) == -1) {
DEBUG(1,("ads_sid_to_name: asprintf failed!\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
rc = ads_search_retry(ads, &msg, exp, attrs);
if (!ADS_ERR_OK(rc)) {
status = ads_ntstatus(rc);
DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc)));
goto done;
}
if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) {
goto done;
}
*name = ads_pull_username(ads, mem_ctx, msg);
if (!*name) {
DEBUG(1,("ads_sid_to_name: ads_pull_username retuned NULL!\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
*type = ads_atype_map(atype);
status = NT_STATUS_OK;
DEBUG(3,("ads sid_to_name mapped %s\n", *name));
done:
if (msg) ads_msgfree(ads, msg);
SAFE_FREE(exp);
SAFE_FREE(sidstr);
return status;
}
#endif

View File

@ -0,0 +1,96 @@
/*
Unix SMB/CIFS implementation.
Some Helpful wrappers on LDAP
Copyright (C) Andrew Tridgell 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#ifdef HAVE_LDAP
/*
a wrapper around ldap_search_s that retries depending on the error code
this is supposed to catch dropped connections and auto-reconnect
*/
ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope,
const char *exp,
const char **attrs, void **res)
{
ADS_STATUS status;
int count = 3;
char *bp;
if (!ads->ld &&
time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) {
return ADS_ERROR(LDAP_SERVER_DOWN);
}
bp = strdup(bind_path);
if (!bp)
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
while (count--) {
status = ads_do_search_all(ads, bp, scope, exp, attrs, res);
if (ADS_ERR_OK(status)) {
DEBUG(5,("Search for %s gave %d replies\n",
exp, ads_count_replies(ads, *res)));
free(bp);
return status;
}
if (*res) ads_msgfree(ads, *res);
*res = NULL;
DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
ads->config.realm, ads_errstr(status)));
if (ads->ld) {
ldap_unbind(ads->ld);
}
ads->ld = NULL;
status = ads_connect(ads);
if (!ADS_ERR_OK(status)) {
DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
ads_errstr(status)));
ads_destroy(&ads);
free(bp);
return status;
}
}
free(bp);
DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status)));
return status;
}
ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
const char *exp,
const char **attrs)
{
return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
exp, attrs, res);
}
ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res,
const char *dn,
const char **attrs)
{
return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE,
"(objectclass=*)", attrs, res);
}
#endif

27
source/script/creategroup Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
# Example script for 'add group command'. Handle weird NT group
# names. First attempt to create the group directly, if that fails
# then create a random group and print the numeric group id.
#
# Note that this is only an example and assumes /dev/urandom.
#
# Volker
GROUPNAME="$1"
ITERS=0
while ! /usr/sbin/groupadd "$GROUPNAME" > /dev/null 2>&1
do
# we had difficulties creating that group. Maybe the name was
# too weird, or it already existed. Create a random name.
GROUPNAME=nt-$(dd if=/dev/urandom bs=16 count=1 2>/dev/null | md5sum | cut -b 1-5)
ITERS=$(expr "$ITERS" + 1)
if [ "$ITERS" -gt 10 ]
then
# Too many attempts
exit 1
fi
done
getent group | grep ^"$GROUPNAME": | cut -d : -f 3