Index: conf/cupsd.conf.in =================================================================== --- conf/cupsd.conf.in (revision 9351) +++ conf/cupsd.conf.in (revision 9352) @@ -45,6 +45,12 @@ # Set the default printer/job policies... + # Job/subscription privacy... + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateAccess default + # Job-related operations must be done by the owner or an administrator... Order deny,allow @@ -63,14 +69,14 @@ # All printer operations require a printer operator to authenticate... - + AuthType Default Require user @CUPS_DEFAULT_PRINTOPERATOR_AUTH@ Order deny,allow # Only the owner or an administrator can cancel or authenticate a job... - + Require user @OWNER @CUPS_DEFAULT_PRINTOPERATOR_AUTH@ Order deny,allow @@ -82,6 +88,12 @@ # Set the authenticated printer/job policies... + # Job/subscription privacy... + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateAccess default + # Job-related operations must be done by the owner or an administrator... AuthType Default @@ -102,14 +114,14 @@ # All printer operations require a printer operator to authenticate... - + AuthType Default Require user @CUPS_DEFAULT_PRINTOPERATOR_AUTH@ Order deny,allow # Only the owner or an administrator can cancel or authenticate a job... - + AuthType Default Require user @OWNER @CUPS_DEFAULT_PRINTOPERATOR_AUTH@ Order deny,allow Index: doc/help/ref-cupsd-conf.html.in =================================================================== --- doc/help/ref-cupsd-conf.html.in (revision 9351) +++ doc/help/ref-cupsd-conf.html.in (revision 9352) @@ -1479,6 +1479,48 @@ HREF="#ServerRoot">ServerRoot directory.

+

CUPS 1.5JobPrivateAccess

+ +

Examples

+ +
+JobPrivateAccess all
+JobPrivateAccess default
+JobPrivateAccess {user|@group|@ACL|@OWNER|@SYSTEM}+
+
+ +

Description

+ +

The JobPrivateAccess directive specifies the access list for a +job's private values. The "default" access list is "@OWNER @SYSTEM". "@ACL" maps +to the printer's requesting-user-name-allowed or requesting-user-name-denied +values.

+ +

The JobPrivateAccess directive must appear inside a Policy section.

+ + +

CUPS 1.5JobPrivateValues

+ +

Examples

+ +
+JobPrivateValues all
+JobPrivateValues default
+JobPrivateValues none
+JobPrivateValues attribute-name-1 [ ... attribute-name-N ]
+
+ +

Description

+ +

The JobPrivateValues directive specifies the list of job values +to make private. The "default" values are "job-name", +"job-originating-host-name", and "job-originating-user-name".

+ +

The JobPrivateValues directive must appear inside a Policy section.

+ +

CUPS 1.2/Mac OS X 10.5JobRetryInterval

Examples

@@ -2985,6 +3027,49 @@ can be specified to listen on multiple ports.

+

CUPS 1.5SubscriptionPrivateAccess

+ +

Examples

+ +
+SubscriptionPrivateAccess all
+SubscriptionPrivateAccess default
+SubscriptionPrivateAccess {user|@group|@ACL|@OWNER|@SYSTEM}+
+
+ +

Description

+ +

The SubscriptionPrivateAccess directive specifies the access list for a +subscription's private values. The "default" access list is "@OWNER @SYSTEM". +"@ACL" maps to the printer's requesting-user-name-allowed or +requesting-user-name-denied values.

+ +

The SubscriptionPrivateAccess directive must appear inside a Policy section.

+ + +

CUPS 1.5SubscriptionPrivateValues

+ +

Examples

+ +
+SubscriptionPrivateValues all
+SubscriptionPrivateValues default
+SubscriptionPrivateValues none
+SubscriptionPrivateValues attribute-name-1 [ ... attribute-name-N ]
+
+ +

Description

+ +

The SubscriptionPrivateValues directive specifies the list of +subscription values to make private. The "default" values are "notify-events", +"notify-pull-method", "notify-recipient-uri", "notify-subscriber-user-name", and +"notify-user-data".

+ +

The SubscriptionPrivateValues directive must appear inside a Policy section.

+ +

SystemGroup

Examples

Index: man/cupsd.conf.man.in =================================================================== --- man/cupsd.conf.man.in (revision 9351) +++ man/cupsd.conf.man.in (revision 9352) @@ -12,7 +12,7 @@ .\" which should have been included with this file. If this file is .\" file is missing or damaged, see the license at "http://www.cups.org/". .\" -.TH cupsd.conf 5 "CUPS" "28 January 2010" "Apple Inc." +.TH cupsd.conf 5 "CUPS" "5 November 2010" "Apple Inc." .SH NAME cupsd.conf \- server configuration file for cups .SH DESCRIPTION @@ -400,6 +400,26 @@ Specifies the number of seconds to wait before killing the filters and backend associated with a canceled or held job. .TP 5 +JobPrivateAccess all +.TP 5 +JobPrivateAccess default +.TP 5 +JobPrivateAccess {user|@group|@ACL|@OWNER|@SYSTEM}+ +.br +Specifies an access list for a job's private values. The "default" access list +is "@OWNER @SYSTEM". "@ACL" maps to the printer's requesting-user-name-allowed +or requesting-user-name-denied values. +.TP 5 +JobPrivateValues all +.TP 5 +JobPrivateValues default +.TP 5 +JobPrivateValues none +.TP 5 +JobPrivateValues attribute-name-1 [ ... attribute-name-N ] +Specifies the list of job values to make private. The "default" values are +"job-name", "job-originating-host-name", and "job-originating-user-name". +.TP 5 JobRetryInterval seconds .br Specifies the interval between retries of jobs in seconds. @@ -686,6 +706,27 @@ .br Listens on the specified port for encrypted connections. .TP 5 +SubscriptionPrivateAccess all +.TP 5 +SubscriptionPrivateAccess default +.TP 5 +SubscriptionPrivateAccess {user|@group|@ACL|@OWNER|@SYSTEM}+ +.br +Specifies an access list for a subscription's private values. The "default" +access list is "@OWNER @SYSTEM". "@ACL" maps to the printer's +requesting-user-name-allowed or requesting-user-name-denied values. +.TP 5 +SubscriptionPrivateValues all +.TP 5 +SubscriptionPrivateValues default +.TP 5 +SubscriptionPrivateValues none +.TP 5 +SubscriptionPrivateValues attribute-name-1 [ ... attribute-name-N ] +Specifies the list of job values to make private. The "default" values are +"notify-events", "notify-pull-method", "notify-recipient-uri", +"notify-subscriber-user-name", and "notify-user-data". +.TP 5 SystemGroup group-name [group-name ...] .br Specifies the group(s) to use for System class authentication. @@ -708,7 +749,7 @@ .br http://localhost:631/help .SH COPYRIGHT -Copyright 2007-2009 by Apple Inc. +Copyright 2007-2010 by Apple Inc. .\" .\" End of "$Id$". .\" Index: test/run-stp-tests.sh =================================================================== --- test/run-stp-tests.sh (revision 9351) +++ test/run-stp-tests.sh (revision 9352) @@ -736,10 +736,10 @@ # Warning log messages count=`grep '^W ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` -if test $count != 0; then - echo "FAIL: $count warning messages, expected 0." +if test $count != 9; then + echo "FAIL: $count warning messages, expected 9." grep '^W ' /tmp/cups-$user/log/error_log - echo "

FAIL: $count warning messages, expected 0.

" >>$strfile + echo "

FAIL: $count warning messages, expected 9.

" >>$strfile echo "
" >>$strfile
 	grep '^W ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
 	echo "
" >>$strfile Index: test/4.4-subscription-ops.test =================================================================== --- test/4.4-subscription-ops.test (revision 9351) +++ test/4.4-subscription-ops.test (revision 9352) @@ -16,6 +16,7 @@ ATTR charset attributes-charset utf-8 ATTR language attributes-natural-language en ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + ATTR name requesting-user-name $user GROUP subscription ATTR uri notify-recipient-uri testnotify:// @@ -48,6 +49,7 @@ ATTR language attributes-natural-language en ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 ATTR integer notify-subscription-id $notify-subscription-id + ATTR name requesting-user-name $user # What statuses are OK? STATUS client-error-not-found @@ -69,6 +71,7 @@ ATTR charset attributes-charset utf-8 ATTR language attributes-natural-language en ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + ATTR name requesting-user-name $user GROUP subscription ATTR uri notify-recipient-uri testnotify:// @@ -102,6 +105,7 @@ ATTR charset attributes-charset utf-8 ATTR language attributes-natural-language en ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + ATTR name requesting-user-name $user # What statuses are OK? STATUS successful-ok @@ -129,6 +133,7 @@ ATTR charset attributes-charset utf-8 ATTR language attributes-natural-language en ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + ATTR name requesting-user-name $user GROUP subscription ATTR uri notify-recipient-uri testnotify:// Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 9351) +++ CHANGES.txt (revision 9352) @@ -1,8 +1,10 @@ -CHANGES.txt - 2010-11-02 +CHANGES.txt - 2010-11-05 ------------------------ CHANGES IN CUPS V1.5b1 + - The scheduler now provides privacy controls for jobs and subscriptions + (STR #2969) - Added new cupsArrayNew3 API which offers memory management of array elements. - Added several new color spaces to the CUPS raster format (STR #3419) Index: scheduler/policy.c =================================================================== --- scheduler/policy.c (revision 9351) +++ scheduler/policy.c (revision 9352) @@ -14,13 +14,19 @@ * * Contents: * - * cupsdAddPolicy() - Add a policy to the system. + * AddPolicy() - Add a policy to the system. * cupsdAddPolicyOp() - Add an operation to a policy. - * cupsdCheckPolicy() - Check the IPP operation and username against - * a policy. + * cupsdCheckPolicy() - Check the IPP operation and username against a + * policy. * cupsdDeleteAllPolicies() - Delete all policies in memory. * cupsdFindPolicy() - Find a named policy. * cupsdFindPolicyOp() - Find a policy operation. + * cupsdGetPrivateAttrs() - Get the private attributes for the current + * request. + * compare_ops() - Compare two operations. + * compare_policies() - Compare two policies. + * free_policy() - Free the memory used by a policy. + * hash_op() - Generate a lookup hash for the operation. */ /* @@ -28,6 +34,7 @@ */ #include "cupsd.h" +#include /* @@ -263,6 +270,197 @@ /* + * 'cupsdGetPrivateAttrs()' - Get the private attributes for the current + * request. + */ + +cups_array_t * /* O - Array or NULL for no restrictions */ +cupsdGetPrivateAttrs( + cupsd_policy_t *policy, /* I - Policy */ + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *printer, /* I - Printer, if any */ + const char *owner) /* I - Owner of object */ +{ + char *name; /* Current name in access list */ + cups_array_t *access_ptr, /* Access array */ + *attrs_ptr; /* Attributes array */ + const char *username; /* Username associated with request */ + ipp_attribute_t *attr; /* Attribute from request */ + struct passwd *pw; /* User info */ + + +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdGetPrivateAttrs(policy=%p(%s), con=%p(%d), " + "printer=%p(%s), owner=\"%s\")", policy, policy->name, con, + con->http.fd, printer, printer ? printer->name : "", owner); +#endif /* DEBUG */ + + /* + * Get the access and attributes lists that correspond to the request... + */ + +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: %s", + ippOpString(con->request->request.op.operation_id)); +#endif /* DEBUG */ + + switch (con->request->request.op.operation_id) + { + case IPP_GET_SUBSCRIPTIONS : + case IPP_GET_SUBSCRIPTION_ATTRIBUTES : + case IPP_GET_NOTIFICATIONS : + access_ptr = policy->sub_access; + attrs_ptr = policy->sub_attrs; + break; + + default : + access_ptr = policy->job_access; + attrs_ptr = policy->job_attrs; + break; + } + + /* + * If none of the attributes are private, return NULL now... + */ + + if ((name = (char *)cupsArrayFirst(attrs_ptr)) != NULL && + !strcasecmp(name, "none")) + { +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning NULL."); +#endif /* DEBUG */ + + return (NULL); + } + + /* + * Otherwise check the user against the access list... + */ + + if (con->username[0]) + username = con->username; + else if ((attr = ippFindAttribute(con->request, "requesting-user-name", + IPP_TAG_NAME)) != NULL) + username = attr->values[0].string.text; + else + username = "anonymous"; + + if (username[0]) + { + pw = getpwnam(username); + endpwent(); + } + else + pw = NULL; + +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: username=\"%s\"", + username); +#endif /* DEBUG */ + + /* + * Otherwise check the user against the access list... + */ + + for (name = (char *)cupsArrayFirst(access_ptr); + name; + name = (char *)cupsArrayNext(access_ptr)) + { +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: name=%s", name); +#endif /* DEBUG */ + + if (printer && !strcasecmp(name, "@ACL")) + { + char *acl; /* Current ACL user/group */ + + for (acl = (char *)cupsArrayFirst(printer->users); + acl; + acl = (char *)cupsArrayNext(printer->users)) + { + if (acl[0] == '@') + { + /* + * Check group membership... + */ + + if (cupsdCheckGroup(username, pw, acl + 1)) + break; + } + else if (acl[0] == '#') + { + /* + * Check UUID... + */ + + if (cupsdCheckGroup(username, pw, acl)) + break; + } + else if (!strcasecmp(username, acl)) + break; + } + } + else if (owner && !strcasecmp(name, "@OWNER") && + !strcasecmp(username, owner)) + { +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdGetPrivateAttrs: Returning NULL."); +#endif /* DEBUG */ + + return (NULL); + } + else if (!strcasecmp(name, "@SYSTEM")) + { + int i; /* Looping var */ + + for (i = 0; i < NumSystemGroups; i ++) + if (cupsdCheckGroup(username, pw, SystemGroups[i])) + { +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdGetPrivateAttrs: Returning NULL."); +#endif /* DEBUG */ + + return (NULL); + } + } + else if (name[0] == '@') + { + if (cupsdCheckGroup(username, pw, name + 1)) + { +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdGetPrivateAttrs: Returning NULL."); +#endif /* DEBUG */ + + return (NULL); + } + } + else if (!strcasecmp(username, name)) + { +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning NULL."); +#endif /* DEBUG */ + + return (NULL); + } + } + + /* + * No direct access, so return private attributes list... + */ + +#ifdef DEBUG + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning list."); +#endif /* DEBUG */ + + return (attrs_ptr); +} + + +/* * 'compare_ops()' - Compare two operations. */ @@ -293,6 +491,10 @@ static void free_policy(cupsd_policy_t *p) /* I - Policy to free */ { + cupsArrayDelete(p->job_access); + cupsArrayDelete(p->job_attrs); + cupsArrayDelete(p->sub_access); + cupsArrayDelete(p->sub_attrs); cupsArrayDelete(p->ops); cupsdClearString(&p->name); free(p); Index: scheduler/policy.h =================================================================== --- scheduler/policy.h (revision 9351) +++ scheduler/policy.h (revision 9352) @@ -21,10 +21,16 @@ typedef struct { char *name; /* Policy name */ - cups_array_t *ops; /* Operations */ + cups_array_t *job_access, /* Private users/groups for jobs */ + *job_attrs, /* Private attributes for jobs */ + *sub_access, /* Private users/groups for subscriptions */ + *sub_attrs, /* Private attributes for subscriptions */ + *ops; /* Operations */ } cupsd_policy_t; +typedef struct cupsd_printer_s cupsd_printer_t; + /* * Globals... */ @@ -46,6 +52,10 @@ extern void cupsdDeleteAllPolicies(void); extern cupsd_policy_t *cupsdFindPolicy(const char *policy); extern cupsd_location_t *cupsdFindPolicyOp(cupsd_policy_t *p, ipp_op_t op); +extern cups_array_t *cupsdGetPrivateAttrs(cupsd_policy_t *p, + cupsd_client_t *con, + cupsd_printer_t *printer, + const char *owner); /* Index: scheduler/conf.c =================================================================== --- scheduler/conf.c (revision 9351) +++ scheduler/conf.c (revision 9352) @@ -29,6 +29,7 @@ * read_configuration() - Read a configuration file. * read_location() - Read a definition. * read_policy() - Read a definition. + * set_policy_defaults() - Set default policy values as needed. */ /* @@ -209,6 +210,7 @@ static int read_configuration(cups_file_t *fp); static int read_location(cups_file_t *fp, char *name, int linenum); static int read_policy(cups_file_t *fp, char *name, int linenum); +static void set_policy_defaults(cupsd_policy_t *pol); /* @@ -1165,6 +1167,27 @@ DefaultPolicyPtr = p = cupsdAddPolicy("default"); cupsdLogMessage(CUPSD_LOG_INFO, ""); + + cupsdLogMessage(CUPSD_LOG_INFO, "JobPrivateAccess default"); + cupsdAddString(&(p->job_access), "@OWNER"); + cupsdAddString(&(p->job_access), "@SYSTEM"); + + cupsdLogMessage(CUPSD_LOG_INFO, "JobPrivateValues default"); + cupsdAddString(&(p->job_attrs), "job-name"); + cupsdAddString(&(p->job_attrs), "job-originating-host-name"); + cupsdAddString(&(p->job_attrs), "job-originating-user-name"); + + cupsdLogMessage(CUPSD_LOG_INFO, "SubscriptionPrivateAccess default"); + cupsdAddString(&(p->sub_access), "@OWNER"); + cupsdAddString(&(p->sub_access), "@SYSTEM"); + + cupsdLogMessage(CUPSD_LOG_INFO, "SubscriptionPrivateValues default"); + cupsdAddString(&(p->job_attrs), "notify-events"); + cupsdAddString(&(p->job_attrs), "notify-pull-method"); + cupsdAddString(&(p->job_attrs), "notify-recipient-uri"); + cupsdAddString(&(p->job_attrs), "notify-subscriber-user-name"); + cupsdAddString(&(p->job_attrs), "notify-user-data"); + cupsdLogMessage(CUPSD_LOG_INFO, ""); cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow"); @@ -1184,7 +1207,7 @@ "Set-Job-Attributes Create-Job-Subscription " "Renew-Subscription Cancel-Subscription " "Get-Notifications Reprocess-Job Cancel-Current-Job " - "Suspend-Current-Job Resume-Job Cancel-Jobs " + "Suspend-Current-Job Resume-Job " "Cancel-My-Jobs Close-Job CUPS-Move-Job " "CUPS-Authenticate-Job CUPS-Get-Document>"); cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow"); @@ -1212,7 +1235,6 @@ cupsdAddPolicyOp(p, po, IPP_CANCEL_CURRENT_JOB); cupsdAddPolicyOp(p, po, IPP_SUSPEND_CURRENT_JOB); cupsdAddPolicyOp(p, po, IPP_RESUME_JOB); - cupsdAddPolicyOp(p, po, IPP_CANCEL_JOBS); cupsdAddPolicyOp(p, po, IPP_CANCEL_MY_JOBS); cupsdAddPolicyOp(p, po, IPP_CLOSE_JOB); cupsdAddPolicyOp(p, po, CUPS_MOVE_JOB); @@ -1228,7 +1250,7 @@ "Hold-New-Jobs Release-Held-New-Jobs " "Deactivate-Printer Activate-Printer Restart-Printer " "Shutdown-Printer Startup-Printer Promote-Job " - "Schedule-Job-After CUPS-Add-Printer " + "Schedule-Job-After Cancel-Jobs CUPS-Add-Printer " "CUPS-Delete-Printer CUPS-Add-Class CUPS-Delete-Class " "CUPS-Accept-Jobs CUPS-Reject-Jobs CUPS-Set-Default>"); cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow"); @@ -1256,6 +1278,7 @@ cupsdAddPolicyOp(p, po, IPP_STARTUP_PRINTER); cupsdAddPolicyOp(p, po, IPP_PROMOTE_JOB); cupsdAddPolicyOp(p, po, IPP_SCHEDULE_JOB_AFTER); + cupsdAddPolicyOp(p, po, IPP_CANCEL_JOBS); cupsdAddPolicyOp(p, po, CUPS_ADD_PRINTER); cupsdAddPolicyOp(p, po, CUPS_DELETE_PRINTER); cupsdAddPolicyOp(p, po, CUPS_ADD_CLASS); @@ -3689,107 +3712,8 @@ "Missing before on line %d!", linenum); - /* - * Verify that we have an explicit policy for Validate-Job, Cancel-Jobs, - * Cancel-My-Jobs, Close-Job, and CUPS-Get-Document, which ensures that - * upgrades do not introduce new security issues... - */ + set_policy_defaults(pol); - if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL || - op->op == IPP_ANY_OPERATION) - { - if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL && - op->op != IPP_ANY_OPERATION) - { - /* - * Add a new limit for Validate-Job using the Print-Job limit as a - * template... - */ - - cupsdLogMessage(CUPSD_LOG_WARN, - "No limit for Validate-Job defined in policy %s " - "- using Print-Job's policy", pol->name); - - cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB); - } - } - - if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_JOBS)) == NULL || - op->op == IPP_ANY_OPERATION) - { - if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_JOB)) != NULL && - op->op != IPP_ANY_OPERATION) - { - /* - * Add a new limit for Cancel-Jobs using the Cancel-Job limit as a - * template... - */ - - cupsdLogMessage(CUPSD_LOG_WARN, - "No limit for Cancel-Jobs defined in policy %s " - "- using Cancel-Job's policy", pol->name); - - cupsdAddPolicyOp(pol, op, IPP_CANCEL_JOBS); - } - } - - if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_MY_JOBS)) == NULL || - op->op == IPP_ANY_OPERATION) - { - if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL && - op->op != IPP_ANY_OPERATION) - { - /* - * Add a new limit for Cancel-My-Jobs using the Send-Document limit as - * a template... - */ - - cupsdLogMessage(CUPSD_LOG_WARN, - "No limit for Cancel-My-Jobs defined in policy %s " - "- using Send-Document's policy", pol->name); - - cupsdAddPolicyOp(pol, op, IPP_CANCEL_MY_JOBS); - } - } - - if ((op = cupsdFindPolicyOp(pol, IPP_CLOSE_JOB)) == NULL || - op->op == IPP_ANY_OPERATION) - { - if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL && - op->op != IPP_ANY_OPERATION) - { - /* - * Add a new limit for Close-Job using the Send-Document limit as a - * template... - */ - - cupsdLogMessage(CUPSD_LOG_WARN, - "No limit for Close-Job defined in policy %s " - "- using Send-Document's policy", pol->name); - - cupsdAddPolicyOp(pol, op, IPP_CLOSE_JOB); - } - } - - if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL || - op->op == IPP_ANY_OPERATION) - { - if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL && - op->op != IPP_ANY_OPERATION) - { - /* - * Add a new limit for CUPS-Get-Document using the Send-Document - * limit as a template... - */ - - cupsdLogMessage(CUPSD_LOG_WARN, - "No limit for CUPS-Get-Document defined in policy %s " - "- using Send-Document's policy", pol->name); - - cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT); - } - } - return (linenum); } else if (!strcasecmp(line, "...
" + "on line %d.", line, linenum); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + else + { + /* + * Pull out whitespace-delimited values... + */ + + while (*value) + { + /* + * Find the end of the current value... + */ + + for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++); + + if (*valptr) + *valptr++ = '\0'; + + /* + * Save it appropriately... + */ + + if (!strcasecmp(line, "JobPrivateAccess")) + { + /* + * JobPrivateAccess {all|default|user/group list|@@ACL} + */ + + if (!strcasecmp(value, "default")) + { + cupsdAddString(&(pol->job_access), "@OWNER"); + cupsdAddString(&(pol->job_access), "@SYSTEM"); + } + else + cupsdAddString(&(pol->job_access), value); + } + else if (!strcasecmp(line, "JobPrivateValues")) + { + /* + * JobPrivateValues {all|none|default|attribute list} + */ + + if (!strcasecmp(value, "default")) + { + cupsdAddString(&(pol->job_attrs), "job-name"); + cupsdAddString(&(pol->job_attrs), "job-originating-host-name"); + cupsdAddString(&(pol->job_attrs), "job-originating-user-name"); + } + else + cupsdAddString(&(pol->job_attrs), value); + } + else if (!strcasecmp(line, "SubscriptionPrivateAccess")) + { + /* + * SubscriptionPrivateAccess {all|default|user/group list|@@ACL} + */ + + if (!strcasecmp(value, "default")) + { + cupsdAddString(&(pol->sub_access), "@OWNER"); + cupsdAddString(&(pol->sub_access), "@SYSTEM"); + } + else + cupsdAddString(&(pol->sub_access), value); + } + else /* if (!strcasecmp(line, "SubscriptionPrivateValues")) */ + { + /* + * SubscriptionPrivateValues {all|none|default|attribute list} + */ + + if (!strcasecmp(value, "default")) + { + cupsdAddString(&(pol->sub_attrs), "notify-events"); + cupsdAddString(&(pol->sub_attrs), "notify-pull-method"); + cupsdAddString(&(pol->sub_attrs), "notify-recipient-uri"); + cupsdAddString(&(pol->sub_attrs), "notify-subscriber-user-name"); + cupsdAddString(&(pol->sub_attrs), "notify-user-data"); + } + else + cupsdAddString(&(pol->sub_attrs), value); + } + + /* + * Find the next string on the line... + */ + + for (value = valptr; isspace(*value & 255); value ++); + } + } + } else if (!op) { cupsdLogMessage(CUPSD_LOG_ERROR, @@ -3902,5 +3929,183 @@ /* + * 'set_policy_defaults()' - Set default policy values as needed. + */ + +static void +set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */ +{ + cupsd_location_t *op; /* Policy operation */ + + + /* + * Verify that we have an explicit policy for Validate-Job, Cancel-Jobs, + * Cancel-My-Jobs, Close-Job, and CUPS-Get-Document, which ensures that + * upgrades do not introduce new security issues... + */ + + if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL || + op->op == IPP_ANY_OPERATION) + { + if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL && + op->op != IPP_ANY_OPERATION) + { + /* + * Add a new limit for Validate-Job using the Print-Job limit as a + * template... + */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Validate-Job defined in policy %s " + "- using Print-Job's policy.", pol->name); + + cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB); + } + else + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Validate-Job defined in policy %s " + "and no suitable template found.", pol->name); + } + + if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_JOBS)) == NULL || + op->op == IPP_ANY_OPERATION) + { + if ((op = cupsdFindPolicyOp(pol, IPP_PAUSE_PRINTER)) != NULL && + op->op != IPP_ANY_OPERATION) + { + /* + * Add a new limit for Cancel-Jobs using the Pause-Printer limit as a + * template... + */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Cancel-Jobs defined in policy %s " + "- using Pause-Printer's policy.", pol->name); + + cupsdAddPolicyOp(pol, op, IPP_CANCEL_JOBS); + } + else + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Cancel-Jobs defined in policy %s " + "and no suitable template found.", pol->name); + } + + if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_MY_JOBS)) == NULL || + op->op == IPP_ANY_OPERATION) + { + if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL && + op->op != IPP_ANY_OPERATION) + { + /* + * Add a new limit for Cancel-My-Jobs using the Send-Document limit as + * a template... + */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Cancel-My-Jobs defined in policy %s " + "- using Send-Document's policy.", pol->name); + + cupsdAddPolicyOp(pol, op, IPP_CANCEL_MY_JOBS); + } + else + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Cancel-My-Jobs defined in policy %s " + "and no suitable template found.", pol->name); + } + + if ((op = cupsdFindPolicyOp(pol, IPP_CLOSE_JOB)) == NULL || + op->op == IPP_ANY_OPERATION) + { + if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL && + op->op != IPP_ANY_OPERATION) + { + /* + * Add a new limit for Close-Job using the Send-Document limit as a + * template... + */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Close-Job defined in policy %s " + "- using Send-Document's policy.", pol->name); + + cupsdAddPolicyOp(pol, op, IPP_CLOSE_JOB); + } + else + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Close-Job defined in policy %s " + "and no suitable template found.", pol->name); + } + + if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL || + op->op == IPP_ANY_OPERATION) + { + if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL && + op->op != IPP_ANY_OPERATION) + { + /* + * Add a new limit for CUPS-Get-Document using the Send-Document + * limit as a template... + */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for CUPS-Get-Document defined in policy %s " + "- using Send-Document's policy.", pol->name); + + cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT); + } + else + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for CUPS-Get-Document defined in policy %s " + "and no suitable template found.", pol->name); + } + + /* + * Verify we have JobPrivateAccess, JobPrivateValues, + * SubscriptionPrivateAccess, and SubscriptionPrivateValues in the policy. + */ + + if (!pol->job_access) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "No JobPrivateAccess defined in policy %s " + "- using defaults.", pol->name); + cupsdAddString(&(pol->job_access), "@OWNER"); + cupsdAddString(&(pol->job_access), "@SYSTEM"); + } + + if (!pol->job_attrs) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "No JobPrivateValues defined in policy %s " + "- using defaults.", pol->name); + cupsdAddString(&(pol->job_attrs), "job-name"); + cupsdAddString(&(pol->job_attrs), "job-originating-host-name"); + cupsdAddString(&(pol->job_attrs), "job-originating-user-name"); + } + + if (!pol->sub_access) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "No SubscriptionPrivateAccess defined in policy %s " + "- using defaults.", pol->name); + cupsdAddString(&(pol->sub_access), "@OWNER"); + cupsdAddString(&(pol->sub_access), "@SYSTEM"); + } + + if (!pol->sub_attrs) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "No SubscriptionPrivateValues defined in policy %s " + "- using defaults.", pol->name); + cupsdAddString(&(pol->sub_attrs), "notify-events"); + cupsdAddString(&(pol->sub_attrs), "notify-pull-method"); + cupsdAddString(&(pol->sub_attrs), "notify-recipient-uri"); + cupsdAddString(&(pol->sub_attrs), "notify-subscriber-user-name"); + cupsdAddString(&(pol->sub_attrs), "notify-user-data"); + } +} + + +/* * End of "$Id$". */ Index: scheduler/ipp.c =================================================================== --- scheduler/ipp.c (revision 9351) +++ scheduler/ipp.c (revision 9352) @@ -167,7 +167,8 @@ int quickcopy); static void close_job(cupsd_client_t *con, ipp_attribute_t *uri); static void copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra, - ipp_tag_t group, int quickcopy); + ipp_tag_t group, int quickcopy, + cups_array_t *exclude); static int copy_banner(cupsd_client_t *con, cupsd_job_t *job, const char *name); static int copy_file(const char *from, const char *to); @@ -175,13 +176,14 @@ const char *to); static void copy_job_attrs(cupsd_client_t *con, cupsd_job_t *job, - cups_array_t *ra); + cups_array_t *ra, cups_array_t *exclude); static void copy_printer_attrs(cupsd_client_t *con, cupsd_printer_t *printer, cups_array_t *ra); static void copy_subscription_attrs(cupsd_client_t *con, cupsd_subscription_t *sub, - cups_array_t *ra); + cups_array_t *ra, + cups_array_t *exclude); static void create_job(cupsd_client_t *con, ipp_attribute_t *uri); static cups_array_t *create_requested_array(ipp_t *request); static void create_subscription(cupsd_client_t *con, ipp_attribute_t *uri); @@ -4940,7 +4942,8 @@ ipp_t *from, /* I - Source request */ cups_array_t *ra, /* I - Requested attributes */ ipp_tag_t group, /* I - Group to copy */ - int quickcopy) /* I - Do a quick copy? */ + int quickcopy, /* I - Do a quick copy? */ + cups_array_t *exclude) /* I - Attributes to exclude? */ { ipp_attribute_t *fromattr; /* Source attribute */ @@ -4962,6 +4965,23 @@ fromattr->group_tag != IPP_TAG_ZERO) || !fromattr->name) continue; + if (exclude && + (cupsArrayFind(exclude, fromattr->name) || + cupsArrayFind(exclude, "all"))) + { + /* + * We need to exclude this attribute for security reasons; we require the + * job-id and job-printer-uri attributes regardless of the security + * settings for IPP conformance. + * + * Subscription attribute security is handled by copy_subscription_attrs(). + */ + + if (strcmp(fromattr->name, "job-id") && + strcmp(fromattr->name, "job-printer-uri")) + continue; + } + if (!ra || cupsArrayFind(ra, fromattr->name)) { /* @@ -5608,7 +5628,8 @@ static void copy_job_attrs(cupsd_client_t *con, /* I - Client connection */ cupsd_job_t *job, /* I - Job */ - cups_array_t *ra) /* I - Requested attributes array */ + cups_array_t *ra, /* I - Requested attributes array */ + cups_array_t *exclude) /* I - Private attributes array */ { char job_uri[HTTP_MAX_URI]; /* Job URI */ @@ -5621,26 +5642,34 @@ con->servername, con->serverport, "/jobs/%d", job->id); - if (!ra || cupsArrayFind(ra, "document-count")) - ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, - "document-count", job->num_files); + if (!cupsArrayFind(exclude, "all")) + { + if ((!exclude || !cupsArrayFind(exclude, "document-count")) && + (!ra || cupsArrayFind(ra, "document-count"))) + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, + "document-count", job->num_files); - if (!ra || cupsArrayFind(ra, "job-media-progress")) - ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, - "job-media-progress", job->progress); + if ((!exclude || !cupsArrayFind(exclude, "job-media-progress")) && + (!ra || cupsArrayFind(ra, "job-media-progress"))) + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, + "job-media-progress", job->progress); - if (!ra || cupsArrayFind(ra, "job-more-info")) - ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, - "job-more-info", NULL, job_uri); + if ((!exclude || !cupsArrayFind(exclude, "job-more-info")) && + (!ra || cupsArrayFind(ra, "job-more-info"))) + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, + "job-more-info", NULL, job_uri); - if (job->state_value > IPP_JOB_PROCESSING && - (!ra || cupsArrayFind(ra, "job-preserved"))) - ippAddBoolean(con->response, IPP_TAG_JOB, "job-preserved", - job->num_files > 0); + if (job->state_value > IPP_JOB_PROCESSING && + (!exclude || !cupsArrayFind(exclude, "job-preserved")) && + (!ra || cupsArrayFind(ra, "job-preserved"))) + ippAddBoolean(con->response, IPP_TAG_JOB, "job-preserved", + job->num_files > 0); - if (!ra || cupsArrayFind(ra, "job-printer-up-time")) - ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, - "job-printer-up-time", time(NULL)); + if ((!exclude || !cupsArrayFind(exclude, "job-printer-up-time")) && + (!ra || cupsArrayFind(ra, "job-printer-up-time"))) + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, + "job-printer-up-time", time(NULL)); + } if (!ra || cupsArrayFind(ra, "job-state-reasons")) add_job_state_reasons(con, job); @@ -5649,7 +5678,7 @@ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL, job_uri); - copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0); + copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0, exclude); } @@ -5821,7 +5850,7 @@ for (i = 0; i < printer->num_history; i ++) copy_attrs(history->values[i].collection = ippNew(), printer->history[i], - NULL, IPP_TAG_ZERO, 0); + NULL, IPP_TAG_ZERO, 0, NULL); } if (!ra || cupsArrayFind(ra, "printer-state-message")) @@ -5875,10 +5904,10 @@ if (!ra || cupsArrayFind(ra, "queued-job-count")) add_queued_job_count(con, printer); - copy_attrs(con->response, printer->attrs, ra, IPP_TAG_ZERO, 0); + copy_attrs(con->response, printer->attrs, ra, IPP_TAG_ZERO, 0, NULL); if (printer->ppd_attrs) - copy_attrs(con->response, printer->ppd_attrs, ra, IPP_TAG_ZERO, 0); - copy_attrs(con->response, CommonData, ra, IPP_TAG_ZERO, IPP_TAG_COPY); + copy_attrs(con->response, printer->ppd_attrs, ra, IPP_TAG_ZERO, 0, NULL); + copy_attrs(con->response, CommonData, ra, IPP_TAG_ZERO, IPP_TAG_COPY, NULL); } @@ -5890,7 +5919,8 @@ copy_subscription_attrs( cupsd_client_t *con, /* I - Client connection */ cupsd_subscription_t *sub, /* I - Subscription */ - cups_array_t *ra) /* I - Requested attributes array */ + cups_array_t *ra, /* I - Requested attributes array */ + cups_array_t *exclude) /* I - Private attributes array */ { ipp_attribute_t *attr; /* Current attribute */ char printer_uri[HTTP_MAX_URI]; @@ -5900,56 +5930,92 @@ const char *name; /* Current event name */ + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "copy_subscription_attrs(con=%p, sub=%p, ra=%p, exclude=%p)", + con, sub, ra, exclude); + /* * Copy the subscription attributes to the response using the * requested-attributes attribute that may be provided by the client. */ - if (!ra || cupsArrayFind(ra, "notify-events")) + if (!exclude || !cupsArrayFind(exclude, "all")) { - if ((name = cupsdEventName((cupsd_eventmask_t)sub->mask)) != NULL) + if ((!exclude || !cupsArrayFind(exclude, "notify-events")) && + (!ra || cupsArrayFind(ra, "notify-events"))) { - /* - * Simple event list... - */ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_subscription_attrs: notify-events"); - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, - (ipp_tag_t)(IPP_TAG_KEYWORD | IPP_TAG_COPY), - "notify-events", NULL, name); + if ((name = cupsdEventName((cupsd_eventmask_t)sub->mask)) != NULL) + { + /* + * Simple event list... + */ + + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, + (ipp_tag_t)(IPP_TAG_KEYWORD | IPP_TAG_COPY), + "notify-events", NULL, name); + } + else + { + /* + * Complex event list... + */ + + for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) + if (sub->mask & mask) + count ++; + + attr = ippAddStrings(con->response, IPP_TAG_SUBSCRIPTION, + (ipp_tag_t)(IPP_TAG_KEYWORD | IPP_TAG_COPY), + "notify-events", count, NULL, NULL); + + for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) + if (sub->mask & mask) + { + attr->values[count].string.text = + (char *)cupsdEventName((cupsd_eventmask_t)mask); + + count ++; + } + } } - else - { - /* - * Complex event list... - */ - for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) - if (sub->mask & mask) - count ++; + if ((!exclude || !cupsArrayFind(exclude, "notify-lease-duration")) && + (!sub->job && (!ra || cupsArrayFind(ra, "notify-lease-duration")))) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-lease-duration", sub->lease); - attr = ippAddStrings(con->response, IPP_TAG_SUBSCRIPTION, - (ipp_tag_t)(IPP_TAG_KEYWORD | IPP_TAG_COPY), - "notify-events", count, NULL, NULL); + if ((!exclude || !cupsArrayFind(exclude, "notify-recipient-uri")) && + (sub->recipient && (!ra || cupsArrayFind(ra, "notify-recipient-uri")))) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, + "notify-recipient-uri", NULL, sub->recipient); + else if ((!exclude || !cupsArrayFind(exclude, "notify-pull-method")) && + (!ra || cupsArrayFind(ra, "notify-pull-method"))) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, + "notify-pull-method", NULL, "ippget"); - for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) - if (sub->mask & mask) - { - attr->values[count].string.text = - (char *)cupsdEventName((cupsd_eventmask_t)mask); + if ((!exclude || !cupsArrayFind(exclude, "notify-subscriber-user-name")) && + (!ra || cupsArrayFind(ra, "notify-subscriber-user-name"))) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME, + "notify-subscriber-user-name", NULL, sub->owner); - count ++; - } - } + if ((!exclude || !cupsArrayFind(exclude, "notify-time-interval")) && + (!ra || cupsArrayFind(ra, "notify-time-interval"))) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-time-interval", sub->interval); + + if (sub->user_data_len > 0 && + (!exclude || !cupsArrayFind(exclude, "notify-user-data")) && + (!ra || cupsArrayFind(ra, "notify-user-data"))) + ippAddOctetString(con->response, IPP_TAG_SUBSCRIPTION, "notify-user-data", + sub->user_data, sub->user_data_len); } if (sub->job && (!ra || cupsArrayFind(ra, "notify-job-id"))) ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-job-id", sub->job->id); - if (!sub->job && (!ra || cupsArrayFind(ra, "notify-lease-duration"))) - ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, - "notify-lease-duration", sub->lease); - if (sub->dest && (!ra || cupsArrayFind(ra, "notify-printer-uri"))) { httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), @@ -5959,28 +6025,9 @@ "notify-printer-uri", NULL, printer_uri); } - if (sub->recipient && (!ra || cupsArrayFind(ra, "notify-recipient-uri"))) - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, - "notify-recipient-uri", NULL, sub->recipient); - else if (!ra || cupsArrayFind(ra, "notify-pull-method")) - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, - "notify-pull-method", NULL, "ippget"); - - if (!ra || cupsArrayFind(ra, "notify-subscriber-user-name")) - ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME, - "notify-subscriber-user-name", NULL, sub->owner); - if (!ra || cupsArrayFind(ra, "notify-subscription-id")) ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-subscription-id", sub->id); - - if (!ra || cupsArrayFind(ra, "notify-time-interval")) - ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, - "notify-time-interval", sub->interval); - - if (sub->user_data_len > 0 && (!ra || cupsArrayFind(ra, "notify-user-data"))) - ippAddOctetString(con->response, IPP_TAG_SUBSCRIPTION, "notify-user-data", - sub->user_data, sub->user_data_len); } @@ -7004,12 +7051,14 @@ int jobid; /* Job ID */ cupsd_job_t *job; /* Current job */ cupsd_printer_t *printer; /* Current printer */ - char scheme[HTTP_MAX_URI], /* Method portion of URI */ + cupsd_policy_t *policy; /* Current security policy */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ int port; /* Port portion of URI */ - cups_array_t *ra; /* Requested attributes array */ + cups_array_t *ra, /* Requested attributes array */ + *exclude; /* Private attributes array */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_job_attrs(%p[%d], %s)", con, @@ -7082,20 +7131,18 @@ printer = cupsdFindDest(job->dest); if (printer) + policy = printer->op_policy_ptr; + else + policy = DefaultPolicyPtr; + + if ((status = cupsdCheckPolicy(policy, con, job->username)) != HTTP_OK) { - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, - NULL)) != HTTP_OK) - { - send_http_error(con, status, printer); - return; - } - } - else if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) - { send_http_error(con, status, NULL); return; } + exclude = cupsdGetPrivateAttrs(policy, con, printer, job->username); + /* * Copy attributes... */ @@ -7103,7 +7150,7 @@ cupsdLoadJob(job); ra = create_requested_array(con->request); - copy_job_attrs(con, job, ra); + copy_job_attrs(con, job, ra, exclude); cupsArrayDelete(ra); con->response->request.status.status_code = IPP_OK; @@ -7137,7 +7184,9 @@ cupsd_job_t *job; /* Current job pointer */ cupsd_printer_t *printer; /* Printer */ cups_array_t *list; /* Which job list... */ - cups_array_t *ra; /* Requested attributes array */ + cups_array_t *ra, /* Requested attributes array */ + *exclude; /* Private attributes array */ + cupsd_policy_t *policy; /* Current policy */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs(%p[%d], %s)", con, con->http.fd, @@ -7200,16 +7249,12 @@ */ if (printer) + policy = printer->op_policy_ptr; + else + policy = DefaultPolicyPtr; + + if ((status = cupsdCheckPolicy(policy, con, NULL)) != HTTP_OK) { - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, - NULL)) != HTTP_OK) - { - send_http_error(con, status, printer); - return; - } - } - else if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) - { send_http_error(con, status, NULL); return; } @@ -7395,7 +7440,12 @@ if (i > 0) ippAddSeparator(con->response); - copy_job_attrs(con, job, ra); + exclude = cupsdGetPrivateAttrs(job->printer ? + job->printer->op_policy_ptr : + policy, con, job->printer, + job->username); + + copy_job_attrs(con, job, ra, exclude); } } else @@ -7451,7 +7501,12 @@ count ++; - copy_job_attrs(con, job, ra); + exclude = cupsdGetPrivateAttrs(job->printer ? + job->printer->op_policy_ptr : + policy, con, job->printer, + job->username); + + copy_job_attrs(con, job, ra, exclude); } cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: count=%d", count); @@ -7595,7 +7650,7 @@ copy_attrs(con->response, ((cupsd_event_t *)cupsArrayIndex(sub->events, j))->attrs, NULL, - IPP_TAG_EVENT_NOTIFICATION, 0); + IPP_TAG_EVENT_NOTIFICATION, 0, NULL); } } } @@ -8163,7 +8218,8 @@ * access... */ - if (printer->num_users && username && !user_allowed(printer, username)) + if (cupsArrayCount(printer->users) && username && + !user_allowed(printer, username)) continue; /* @@ -8200,7 +8256,9 @@ { http_status_t status; /* Policy status */ cupsd_subscription_t *sub; /* Subscription */ - cups_array_t *ra; /* Requested attributes array */ + cupsd_policy_t *policy; /* Current security policy */ + cups_array_t *ra, /* Requested attributes array */ + *exclude; /* Private attributes array */ cupsdLogMessage(CUPSD_LOG_DEBUG2, @@ -8226,14 +8284,19 @@ * Check policy... */ - if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : - DefaultPolicyPtr, - con, sub->owner)) != HTTP_OK) + if (sub->dest) + policy = sub->dest->op_policy_ptr; + else + policy = DefaultPolicyPtr; + + if ((status = cupsdCheckPolicy(policy, con, sub->owner)) != HTTP_OK) { send_http_error(con, status, sub->dest); return; } + exclude = cupsdGetPrivateAttrs(policy, con, sub->dest, sub->owner); + /* * Copy the subscription attributes to the response using the * requested-attributes attribute that may be provided by the client. @@ -8241,7 +8304,7 @@ ra = create_requested_array(con->request); - copy_subscription_attrs(con, sub, ra); + copy_subscription_attrs(con, sub, ra, exclude); cupsArrayDelete(ra); @@ -8275,6 +8338,8 @@ int port; /* Port portion of URI */ cupsd_job_t *job; /* Job pointer */ cupsd_printer_t *printer; /* Printer */ + cupsd_policy_t *policy; /* Policy */ + cups_array_t *exclude; /* Private attributes array */ cupsdLogMessage(CUPSD_LOG_DEBUG2, @@ -8338,9 +8403,12 @@ * Check policy... */ - if ((status = cupsdCheckPolicy(printer ? printer->op_policy_ptr : - DefaultPolicyPtr, - con, NULL)) != HTTP_OK) + if (printer) + policy = printer->op_policy_ptr; + else + policy = DefaultPolicyPtr; + + if ((status = cupsdCheckPolicy(policy, con, NULL)) != HTTP_OK) { send_http_error(con, status, printer); return; @@ -8377,8 +8445,13 @@ (!username[0] || !strcasecmp(username, sub->owner))) { ippAddSeparator(con->response); - copy_subscription_attrs(con, sub, ra); + exclude = cupsdGetPrivateAttrs(sub->dest ? sub->dest->op_policy_ptr : + policy, con, sub->dest, + sub->owner); + + copy_subscription_attrs(con, sub, ra, exclude); + count ++; if (limit && count >= limit) break; Index: scheduler/printers.h =================================================================== --- scheduler/printers.h (revision 9351) +++ scheduler/printers.h (revision 9352) @@ -38,7 +38,7 @@ typedef struct cupsd_job_s cupsd_job_t; -typedef struct cupsd_printer_s +struct cupsd_printer_s { char *uri, /* Printer URI */ *hostname, /* Host printer resides on */ @@ -81,8 +81,7 @@ page_limit, /* Maximum number of pages */ k_limit; /* Maximum number of kilobytes */ cups_array_t *quotas; /* Quota records */ - int deny_users, /* 1 = deny, 0 = allow */ - num_users; /* Number of allowed/denied users */ + int deny_users; /* 1 = deny, 0 = allow */ cups_array_t *users; /* Allowed/denied users */ int num_history; /* Number of history collections */ ipp_t **history; /* History data */ @@ -109,7 +108,7 @@ DNSServiceRef ipp_ref, /* Reference for _ipp._tcp,_cups */ printer_ref; /* Reference for _printer._tcp */ #endif /* HAVE_DNSSD */ -} cupsd_printer_t; +}; /*