Skip to content

Commit

Permalink
Handle cases when auth groups are unset
Browse files Browse the repository at this point in the history
Currently, pappl based applications require authentication every time
for any request if authentication module is set, even if authentication
group(s) is set to `None`.

With this PR, admin can set admin and print group to `None`. Every admin
action is allowed if admin group is `None`. For printing jobs,
Validate-Job, Print-Job, Create-Job are allowed, Send-Document if the
requesting client is owner of the job - value of `requesting-user-name`
is used as default value, in case authorization field does not contain
it.

This allows smooth printing to the printer application via CUPS when
printer application uses PAM module to protect against simple attacks.
  • Loading branch information
zdohnal committed Mar 18, 2024
1 parent 988b90a commit 203e31c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pappl/client-auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ papplClientIsAuthorized(
if (!client)
return (HTTP_STATUS_BAD_REQUEST);

if (_papplSystemGroupIsEmpty(client->system->admin_group) &&
httpAddrIsLocalhost(httpGetAddress(client->http)))
return (HTTP_STATUS_CONTINUE);

// Authorize for admin access...
return (_papplClientIsAuthorizedForGroup(client, false, client->system->admin_group, client->system->admin_gid));
}
Expand Down
3 changes: 3 additions & 0 deletions pappl/client-ipp.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ _papplClientProcessIPP(
client->printer = NULL;
client->job = NULL;

if ((attr = ippFindAttribute(client->request, "requesting-user-name", IPP_TAG_NAME)) != NULL)
cupsCopyString(client->username, ippGetString(attr, 0, NULL), sizeof(client->username));

if (charset && strcasecmp(ippGetString(charset, 0, NULL), "us-ascii") && strcasecmp(ippGetString(charset, 0, NULL), "utf-8"))
{
// Bad character set...
Expand Down
24 changes: 24 additions & 0 deletions pappl/printer-ipp.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static void ipp_get_jobs(pappl_client_t *client);
static void ipp_get_printer_attributes(pappl_client_t *client);
static void ipp_hold_new_jobs(pappl_client_t *client);
static void ipp_identify_printer(pappl_client_t *client);
static bool ipp_is_printing_op(pappl_client_t *client);
static void ipp_pause_printer(pappl_client_t *client);
static void ipp_print_job(pappl_client_t *client);
static void ipp_release_held_new_jobs(pappl_client_t *client);
Expand Down Expand Up @@ -785,6 +786,10 @@ bool // O - `true` on success, `false` on failure
_papplPrinterIsAuthorized(
pappl_client_t *client) // I - Client
{
if (_papplSystemGroupIsEmpty(client->printer->print_group) && httpAddrIsLocalhost(httpGetAddress(client->http)) &&
ipp_is_printing_op(client))
return (true);

http_status_t code = _papplClientIsAuthorizedForGroup(client, true, client->printer->print_group, client->printer->print_gid);

if (code == HTTP_STATUS_CONTINUE && client->job && client->job->username && strcmp(client->username, client->job->username))
Expand Down Expand Up @@ -2585,3 +2590,22 @@ valid_job_attributes(

return (valid);
}


static bool // O - `true` if the operation is related to print job and valid, `false` if not
ipp_is_printing_op(pappl_client_t *client) // I - Client
{
if (client->operation_id == IPP_OP_PRINT_JOB)
return (true);

if (client->operation_id == IPP_OP_VALIDATE_JOB)
return (true);

if (client->operation_id == IPP_OP_CREATE_JOB)
return (true);

if (client->operation_id == IPP_OP_SEND_DOCUMENT && client->job && client->job->username && !strcmp(client->username, client->job->username))
return (true);

return (false);
}
14 changes: 14 additions & 0 deletions pappl/system-accessors.c
Original file line number Diff line number Diff line change
Expand Up @@ -2882,3 +2882,17 @@ free_inspector(
free(i->type);
free(i);
}


//
// '_papplSystemGroupIsEmpty()' - Check if group is empty
//

bool // O - `true` if empty, `false` if set
_papplSystemGroupIsEmpty(const char *group) // I - Group name
{
if (!group || !group[0] || !strcmp(group, "none"))
return (true);

return (false);
}
1 change: 1 addition & 0 deletions pappl/system-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ extern _pappl_mime_filter_t *_papplSystemFindMIMEFilter(pappl_system_t *system,
extern _pappl_mime_inspector_t *_papplSystemFindMIMEInspector(pappl_system_t *system, const char *type) _PAPPL_PRIVATE;
extern _pappl_resource_t *_papplSystemFindResourceForLanguage(pappl_system_t *system, const char *language) _PAPPL_PRIVATE;
extern _pappl_resource_t *_papplSystemFindResourceForPath(pappl_system_t *system, const char *path) _PAPPL_PRIVATE;
extern bool _papplSystemGroupIsEmpty(const char *group) _PAPPL_PRIVATE;
extern char *_papplSystemMakeUUID(pappl_system_t *system, const char *printer_name, int job_id, char *buffer, size_t bufsize) _PAPPL_PRIVATE;
extern void _papplSystemNeedClean(pappl_system_t *system) _PAPPL_PRIVATE;
extern void _papplSystemProcessIPP(pappl_client_t *client) _PAPPL_PRIVATE;
Expand Down

0 comments on commit 203e31c

Please sign in to comment.