Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"lpadmin ... -o printer-is-shared=true" does not work for ipp queues without visible reason #4738

Closed
michaelrsweet opened this issue Nov 6, 2015 · 7 comments
Labels
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

@michaelrsweet michaelrsweet commented Nov 6, 2015

Version: 2.1.0
CUPS.org User: jsmeix.suse

I have a remote CUPS server with a queue "foo".

On the local system I create a raw queue that only forwards

to the queue "foo" on the remote CUPS server:

lpadmin -p foofwd -v ipp://server.domain/printers/foo -E

echo $?

0

I can print from the local system via the local foofwd queue.

Now I like to share that foofwd queue on my local system:

lpadmin -p foofwd -o printer-is-shared=true

echo $?

0

In /var/log/cups/error_log (with LogLevel debug) there is:

D ... CUPS-Add-Modify-Printer ipp://localhost:631/printers/foofwd
D ... cupsdIsAuthorized: username="root"
I ... Setting foofwd printer-is-shared to 1 (was 0.)
...

I Saving printers.conf...

But in /etc/cups/printers.conf the foofwd queue is still "Shared No"

In contrast "printer-is-shared=true" works for a "raw" queue

where the DeviceUri is not "ipp://...":

lpadmin -p bar -v socket://dummy.example.org -E


it has by default "Shared Yes" in /etc/cups/printers.conf

and I can toggle it as I like with

lpadmin -p bar -o printer-is-shared=false


versus

lpadmin -p bar -o printer-is-shared=true


I found that this behaviour was already reported in
https://www.cups.org/pipermail/cups/2014-June/026272.html
but without an aswer that explains why CUPS
does not share an ipp print queue.

Therefore I report it now as a bug because
ther are thre issues with that behaviour:

When "lpadmin ... -o printer-is-shared=..." does not work,
it should at least report an error or warning.

"man lpadmin" does not tell anything that
sharing an ipp print queue does not work.

https://www.cups.org/documentation.php/doc-2.1/sharing.html
does not tell anything that sharing an ipp print queue does not work.

There is no debug message in /var/log/cups/error_log
that could help to dind out what the reason is
why sharing an ipp print queue does not work.
Actually the messages in /var/log/cups/error_log
seem to show that it has worked:
"Setting foofwd printer-is-shared to 1 (was 0.)"

I assume there is a good reason why sharing an ipp print queue
does not work but then this reason should be at least documented.

Additionally it is perhaps a minor bug that lpadmin does
neither show an error message nor return an error exit code
in this case.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 6, 2015

CUPS.org User: mike

Johannes,

You cannot re-share a remote printer - this change was made several years ago because it causes a lot of problems when the final server requires authentication.

That said, you should probably be getting an error from lpadmin when you try to set the printer-is-shared attribute to 1... Will use this bug to track that change.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 9, 2015

CUPS.org User: jsmeix.suse

I think the basic question is what "remote printer" means.

I know that the local cupsd cannot re-share a queue that it got
via annoucement from a remote cupsd (e.g. one cannot re-share
a traditional CUPS Browsing reference to a remote queue).

But in my case here my foofwd queue is a local queue
(locally created with lpadmin for the local cupsd)
which has an entry in /etc/cups/printers.conf.

I do not want to re-share it.
I like to share it.

I thought that all queues that exist in /etc/cups/printers.conf
are local queues and that all local queues can be shared.

In my case it seems one cannot share a local queue depending
in an obscure way on its specific DeviceURI.

Initially I detected this behaviour with CUPS 1.3.9 on SLES11
and then I verified that it still exists with CUPS 2.1.0.

In CHANGES-1.3.txt I detected now this entry

  • The scheduler did not prevent remote queues from being
    shared/published.

    which seems to match this issue here but there is no information
    that describes what exactly is meant with "remote queues" here.

For example if local queues with any ipp//... DeviceURI
could not be shared, it would be impossible to share
a local queue for a network printer that is accessed
via an ipp//... DeviceURI.

But somehow this seems to work:

lpadmin -p baz -v ipp://dummy.example.org/something -E

less /etc/cups/printers.conf

...

...
DeviceURI ipp://dummy.example.org/something
...
Shared Yes
...

lpadmin -p baz -o printer-is-shared=false

less /etc/cups/printers.conf

...

...
Shared No
...

lpadmin -p baz -o printer-is-shared=true

less /etc/cups/printers.conf

...

Shared Yes

Therefore I think the real issue is to describe precisely
what "remote queue" actually means in CUPS.

Perhaps for queues that exist in /etc/cups/printers.conf

a new explicit entry

Remote [Yes/No]

could be provided to make it clear
which queue is a "remote queue" and which one is not.

Or alternatively and perhaps even more to the point

Shareable [Yes/No]

to make it clear which queue can be shared and which cannot.

In general regarding my current understanding of the terms
"local/remote queue" and "local/remote printer" see
https://en.opensuse.org/YaST_Printer

(excerpt):

There is a difference between "local/remote queue"
and "local/remote printer":

  • "Local queue" means a print queue which is configured
    on the local computer...

  • "Remote queue" means a print queue which exists on whatever
    computer in the network or on whatever network printer.

  • "Local printer" means a printer device which is directly
    connected to the local computer (usually a USB printer).

  • "Remote printer" means a printer device which is not directly
    connected to the local computer (usually a printer with

    a built-in network interface).

Now I am confused regarding a network printer that is accessed
via an ipp//... DeviceURI versus a queue on a remote CUPS server.

According to my current understanding in both cases
the recipient is a "remote IPP queue" that exists
in the network printer or on the remote CUPS server
so that both cases should behave the same.

In particular I am confused about a (hypothetical?)
big-and-fat network printer that has CUPS built in
and is accessed only via IPP.

Could one share queues in /etc/cups/printers.conf
for network printers with built-in CUPS?

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 9, 2015

CUPS.org User: jsmeix.suse

I guess I found the hardcoded DeviceURI magic that distinguishes
between what is a "Remote Printer" and a "Local Raw Printer"
in scheduler/printers.c

(excerpt):

load_ppd(cupsd_printer_t *p) ...

...

else if (((!strncmp(p->device_uri, "ipp://", 6) ||
           !strncmp(p->device_uri, "ipps://", 7)) &&
          (strstr(p->device_uri, "/printers/") != NULL ||
           strstr(p->device_uri, "/classes/") != NULL)) ||
         ((strstr(p->device_uri, "._ipp.") != NULL ||
           strstr(p->device_uri, "._ipps.") != NULL) &&
          !strcmp(p->device_uri + strlen(p->device_uri) - 5, "/cups")))
{
 /*
  * Tell the client this is really a hard-wired remote printer.
  */

  p->type |= CUPS_PRINTER_REMOTE;

...

 /*
  * Then set the make-and-model accordingly...
  */

  ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
               "printer-make-and-model", NULL, "Remote Printer");

 /*
  * Print all files directly...
  */

  p->raw    = 1;
  p->remote = 1;
}
else
{
 /*
  * Otherwise we have neither - treat this as a "dumb" printer
  * with no PPD file...
  */

  ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
               "printer-make-and-model", NULL, "Local Raw Printer");

  p->raw = 1;
}

and its hardcoded consequence also in scheduler/printers.c

(excerpt)

cupsdSetPrinterAttrs(cupsd_printer_t *p) ...

...

/*

  • Force sharing off for remote queues...
    */

    if (p->type & CUPS_PRINTER_REMOTE)

    p->shared = 0;

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 9, 2015

CUPS.org User: jsmeix.suse

Furthermore there is in scheduler/printers.c

load_ppd(cupsd_printer_t *p) ...

...

if (ppdFindAttr(ppd, "APRemoteQueueID", NULL))
  p->type |= CUPS_PRINTER_REMOTE;

but that is the only place in the CUPS 2.1.0 sources
where I can find "APRemoteQueueID".

Now I wonder what "APRemoteQueueID" is?

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 13, 2015

CUPS.org User: jsmeix.suse

This is only a guess but perhaps I am on the right track:

When there is a queue in /etc/cups/printers.conf
with a DeviceURI that points to a remote CUPS queue
(e.g. when the DeviceURI has the form "ipp://.../printers/...")
then the local cupsd does not treat such a queue as
a "dumb" queue with no PPD file (i.e. as a local raw queue)
instead
it seems the local cupsd treats such a queue like the
traditional CUPS Browsing reference to a remote CUPS queue.

In particular for such a queue one gets printer specific PPD options
from the remote CUPS queue when one asks the local cupsd

via "lpoptions -l":

lpoptions -h localhost -p foofwd -l

Resolution/Resolution : *600 ...
MediaType/Media Type : *Auto PlainPaperL PlainPaper ...
InputSlot/Paper Source: *Auto Manual Cas1 Cas2 Cas3 ...
OutputBin/Paper Destination: *Auto TrayA TrayB TrayC
Duplex/Duplex: *None DuplexNoTumble DuplexTumble
BindEdge/BindingEdge: *Left Top
Booklet/Booklet Printing: *None Left
Collate/Collate: False *True Group StapleCollate ...
StapleLocation/Staple Location: None *TopLeft Top ...

PageSize/Page Size: Letter Legal A5 *A4 ...

This is unexpected because my "foofwd" queue has no PPD file.

If my above assumption is right the problem is that
the cupsd makes a hardcoded decision that a local queue
without PPD file and DeviceURI that points to a remote CUPS queue
behaves in a special way.

According to my current understanding the solution should be
to make it explicit in /etc/cups/printers.conf
how such a queue should behave:
Either as local raw queue
or as some kind of reference or proxy for a remote CUPS queue.

When setting up such a queue the cupsd can of course set
a default for its behaviour but I think it must still
be possible that the admin enforces his desired behaviour.

In short:
I think it must be possible to set up a "dumb" local raw queue
with a DeviceURI that points to a remote CUPS queue.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 17, 2015

CUPS.org User: mike

Raw queues are the only ones to be flagged as remote queues, and then only IPP queues that point to a CUPS server (/cups on the end for Bonjour URIs, /classes and /printers for ipp/ipps URIs).

Source changes (to produce an error) are below.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 17, 2015

"str4738.patch":

Index: scheduler/ipp.c

--- scheduler/ipp.c (revision 12973)
+++ scheduler/ipp.c (working copy)
@@ -978,6 +978,16 @@
if ((attr = ippFindAttribute(con->request, "printer-is-shared",
IPP_TAG_BOOLEAN)) != NULL)
{

  • if (pclass->type & CUPS_PRINTER_REMOTE)
  • {
  • /*
    
  •  \* Cannot re-share remote printers.
    
  •  */
    
  •  send_ipp_status(con, IPP_BAD_REQUEST, _("Cannot change printer-is-shared for remote queues."));
    
  •  return;
    
  • }

if (pclass->shared && !attr->values[0].boolean)
cupsdDeregisterPrinter(pclass, 1);

@@ -2471,6 +2481,16 @@
return;
}

  • if (printer->type & CUPS_PRINTER_REMOTE)
  • {
  • /*
    
  •  \* Cannot re-share remote printers.
    
  •  */
    
  •  send_ipp_status(con, IPP_BAD_REQUEST, _("Cannot change printer-is-shared for remote queues."));
    
  •  return;
    
  • }

if (printer->shared && !attr->values[0].boolean)
cupsdDeregisterPrinter(printer, 1);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.