Bug 383305 - Endless loop when configuring a printer from central CUPS server and permission denied (403)
Summary: Endless loop when configuring a printer from central CUPS server and permissi...
Status: RESOLVED FIXED
Alias: None
Product: print-manager
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: 0.3.0
Platform: Gentoo Packages Linux
: NOR major
Target Milestone: ---
Assignee: Daniel Nicoletti
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-08-09 08:47 UTC by Oliver Freyermuth
Modified: 2017-09-27 17:03 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In: 17.08.2


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oliver Freyermuth 2017-08-09 08:47:21 UTC
When attempting configuring a printer e.g. from a central CUPS server which responds to the 
POST /admin/ HTTP/1.1
request with 403 (Forbidden), configure-printer enters and endless loop, retrying and retrying the "POST" tens of times per second. 

This leads to severe network contention and fills the logfiles of CUPS servers, so I regards this as a major issue in environments with a central CUPS server. As a solution, only killing "configure-printer" or restarting KDE helps. 

To reproduce: Enter the printer configuration via PlasmaShells tray, configure any printer from a central cups server, and click "Apply". 

Let me know if more info is needed.
Comment 1 Oliver Freyermuth 2017-08-09 09:04:28 UTC
I believe the endless loop starts here:
https://github.com/KDE/print-manager/blob/afd4609014e9aa938cb02be858f880deb56ade8e/libkcups/KCupsRequest.cpp#L564
Comment 2 Daniel Nicoletti 2017-08-09 10:10:07 UTC
That line is only a problem if there is a programming error with Qt parenting, which is unlikely.

What can help here is the server configuration tho I sadly don't have much more time to investigate issues on this.
Comment 3 Oliver Freyermuth 2017-08-09 10:17:49 UTC
Well, if the server responds with 403 but the client retries (endlessly), I'd say it's clearly a client-side bug. So something must go wrong with the error handling in the forked connection thread. 

The related CUPS server config part is:
<Location /admin>
  Order allow,deny
  Allow from INSERTADMINHOSTIPHERE
</Location>

Of course I am trying from a normal client, not the admin machine.
Comment 4 Oliver Freyermuth 2017-08-09 10:31:39 UTC
You made me have a deeper look at the code, the bug is obvious in:

https://github.com/KDE/print-manager/blob/master/libkcups/KCupsConnection.cpp

1) KCupsConnection::request() calls retry(). 
2) KCupsConnection::retry() handles (status == IPP_FORBIDDEN), and if password_retries == 0, will set force_auth to true.
3) If force_auth is true, cupsDoAuthentication will be called. 
4) cupsDoAuthentication will NOT call the password_cb callback, since it will (again) get a 403. for this reason, password_retries will NOT be bumped. 
5) Since cupsDoAuthentication returned -1, KCupsConnection::retry() will return true. 
6) We go back to Step 1. 

That will happen endlessly. 

On a side-note, debug output is broken: 
qCDebug(LIBKCUPS) << "Called cupsDoAuthentication(), success:" << (ret == -1 ? true : false);
Here "-1" indicates failure, not success. 

Does this help to resolve the issue?
Comment 5 Oliver Freyermuth 2017-08-09 10:40:31 UTC
If you allow for a comment: 
I'd say relying on the callback function to work (and thus relying on cups API callback behaviour to break the loop) is not a good idea in general. Maybe, at least as additional safety, it is better to have an additional exit condition.
Comment 6 Oliver Freyermuth 2017-08-11 11:31:06 UTC
Can you confirm my understanding of the code is correct? 
If yes, and you tell me which way you prefer it to be solved:
a) adding an additional error counting mechanism independent from the callback
b) immedate erroring if 403 is received when attempted as root user
c) both
I could also prepare a PR.
Comment 7 Daniel Nicoletti 2017-08-14 10:28:07 UTC
To be honest I'm not sure what is best.
I think b is received if the password is wrong, but I'm not sure (old code :P)
if you can try both solutions would be great, I'll have more time to look into this in around 2 weeks, so please ping me.
Thanks.
Comment 8 Oliver Freyermuth 2017-08-15 10:53:00 UTC
Hi, 
it seems you are correct, the CUPS server may also return 403 if the user uses a wrong password (I was pretty sure it would return NOT_AUTHENTICATED or NOT_AUTHORIZED in that case...). 

Based on that, I have created a very generic fix: 
https://github.com/KDE/print-manager/pull/2
It works for me against a CUPS-Server with IP whitelist / blacklist (i.e. no endless loop anymore!), and I can still authenticate to a local CUPS as root.
Comment 9 Oliver Freyermuth 2017-08-15 11:56:10 UTC
Hi, 

just to document: I have now uploaded the PR, as seems to be the correct way for KDE contributions, to:
https://phabricator.kde.org/D7325
Comment 10 Oliver Freyermuth 2017-09-04 11:34:44 UTC
Hi, 

here the friendly "ping", as requested. 
Cheers, Oliver