diff --git a/cups/scheduler/ipp.c b/cups/scheduler/ipp.c index 8d2c79baa..cee68cf8b 100644 --- a/cups/scheduler/ipp.c +++ b/cups/scheduler/ipp.c @@ -6209,6 +6209,11 @@ get_document(cupsd_client_t *con, /* I - Client connection */ int port; /* Port portion of URI */ char filename[1024], /* Filename for document */ format[1024]; /* Format for document */ + security_id_t clisid; /* SELinux SID for the client */ + security_id_t jsid; /* SELinux SID for the job */ + struct avc_entry_ref avcref; /* Pointer to the access vector cache */ + security_class_t tclass; /* Object class for the SELinux check */ + access_vector_t avr; /* Access method being requested */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_document(%p[%d], %s)", con, @@ -6283,6 +6288,52 @@ get_document(cupsd_client_t *con, /* I - Client connection */ return; } + if (is_selinux_mls_enabled () ) + { + static int avc_initialized = 0; + if (! avc_initialized++) + { + if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, "check_context: unable avc_init"); + return ; + } + + } + cupsdLogMessage(CUPSD_LOG_DEBUG2, "client context: %s", con->scon); + avc_context_to_sid(con->scon, &clisid); + avc_entry_ref_init(&avcref); + avc_context_to_sid(job->scon, &jsid); + + tclass = string_to_security_class("file"); + if (tclass <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "GetDocument: SELinux failed to translate security class \"file\""); + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("SELinux failed to translate security class \"file\" while processing job #%d."), + jobid); + return; + } + + avr = string_to_av_perm(tclass, "read"); + if (avr <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "GetDocument: SELinux failed to translate av perm \"read\" of security class \"file\""); + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("SELinux failed to translate av perm \"read\" of security class \"file\" while processing job #%d."), + jobid); + return; + } + + if( avc_has_perm(clisid, jsid, tclass, avr, &avcref, NULL) ) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "GetDocument: Refusing Job %d due to SE level", job->id); + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid); + return; + } + } /* * Get the document number... */ @@ -6356,6 +6407,11 @@ get_job_attrs(cupsd_client_t *con, /* I - Client connection */ int port; /* Port portion of URI */ cups_array_t *ra, /* Requested attributes array */ *exclude; /* Private attributes array */ + security_id_t clisid; /* SELinux SID for the client */ + security_id_t jsid; /* SELinux SID for the job */ + struct avc_entry_ref avcref; /* Pointer to the access vector cache */ + security_class_t tclass; /* Object class for the SELinux check */ + access_vector_t avr; /* Access method being requested */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_job_attrs(%p[%d], %s)", con, @@ -6419,6 +6475,52 @@ get_job_attrs(cupsd_client_t *con, /* I - Client connection */ return; } + if (is_selinux_mls_enabled () ) + { + static int avc_initialized = 0; + if (! avc_initialized++) + { + if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, "check_context: unable avc_init"); + return ; + } + + } + cupsdLogMessage(CUPSD_LOG_DEBUG2, "client context: %s", con->scon); + avc_context_to_sid(con->scon, &clisid); + avc_entry_ref_init(&avcref); + avc_context_to_sid(job->scon, &jsid); + + tclass = string_to_security_class("file"); + if (tclass <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "GetJobAttrs: SELinux failed to translate security class \"file\""); + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("SELinux failed to translate security class \"file\" while processing job #%d."), + jobid); + return; + } + + avr = string_to_av_perm(tclass, "read"); + if (avr <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "GetJobAttrs: SELinux failed to translate av perm \"read\" of security class \"file\""); + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("SELinux failed to translate av perm \"read\" of security class \"file\" while processing job #%d."), + jobid); + return; + } + + if( avc_has_perm(clisid, jsid, tclass, avr, &avcref, NULL) ) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "GetJobAttrs: Refusing Job %d due to SE level", job->id); + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid); + return; + } + } /* * Check policy... */ @@ -6487,6 +6589,11 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ cups_array_t *ra, /* Requested attributes array */ *exclude; /* Private attributes array */ cupsd_policy_t *policy; /* Current policy */ + security_id_t clisid; /* SELinux SID for the client */ + security_id_t jsid; /* SELinux SID for the job */ + struct avc_entry_ref avcref; /* Pointer to the access vector cache */ + security_class_t tclass; /* Object class for the SELinux check */ + access_vector_t avr; /* Access method being requested */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs(%p[%d], %s)", con, con->number, @@ -6736,6 +6843,39 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ cupsdLogClient(con, CUPSD_LOG_INFO, "Limiting Get-Jobs response to %d jobs.", limit); } + if (is_selinux_mls_enabled () ) + { + static int avc_initialized = 0; + if (! avc_initialized++) + { + if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, "check_context: unable avc_init"); + return ; + } + + } + cupsdLogMessage(CUPSD_LOG_DEBUG2, "client context: %s", con->scon); + avc_context_to_sid(con->scon, &clisid); + avc_entry_ref_init(&avcref); + + tclass = string_to_security_class("file"); + if (tclass <= 0) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, + "SELinux failed to translate security class \"file\""); + return; + } + + avr = string_to_av_perm(tclass, "read"); + if (avr <= 0) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, + "SELinux failed to translate av perm \"read\" of security class \"file\""); + return; + } + } + /* * OK, build a list of jobs for this printer... */ @@ -6771,6 +6911,15 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ continue; } } + if (is_selinux_mls_enabled () ) + { + avc_context_to_sid(job->scon, &jsid); + if( avc_has_perm(clisid, jsid, tclass, avr, &avcref, NULL) ) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "GetJobs: Skiping Job %d due to SE level", job->id); + continue; + } + } if (i > 0) ippAddSeparator(con->response); @@ -6833,6 +6982,15 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ } } + if (is_selinux_mls_enabled () ) + { + avc_context_to_sid(job->scon, &jsid); + if( avc_has_perm(clisid, jsid, tclass, avr, &avcref, NULL) ) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "GetJobs: Skiping Job %d due to SE level", job->id); + continue; + } + } if (username[0] && _cups_strcasecmp(username, job->username)) continue; @@ -9006,6 +9164,11 @@ release_job(cupsd_client_t *con, /* I - Client connection */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ int port; /* Port portion of URI */ cupsd_job_t *job; /* Job information */ + security_id_t clisid; /* SELinux SID for the client */ + security_id_t jsid; /* SELinux SID for the job */ + struct avc_entry_ref avcref; /* Pointer to the access vector cache */ + security_class_t tclass; /* Object class for the SELinux check */ + access_vector_t avr; /* Access method being requested */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_job(%p[%d], %s)", con, @@ -9069,6 +9232,52 @@ release_job(cupsd_client_t *con, /* I - Client connection */ return; } + if (is_selinux_mls_enabled () ) + { + static int avc_initialized = 0; + if (! avc_initialized++) + { + if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, "check_context: unable avc_init"); + return ; + } + + } + cupsdLogMessage(CUPSD_LOG_DEBUG2, "client context: %s", con->scon); + avc_context_to_sid(con->scon, &clisid); + avc_entry_ref_init(&avcref); + avc_context_to_sid(job->scon, &jsid); + + tclass = string_to_security_class("file"); + if (tclass <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "ReleaseJob: SELinux failed to translate security class \"file\""); + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("SELinux failed to translate security class \"file\" while processing job #%d."), + jobid); + return; + } + + avr = string_to_av_perm(tclass, "write"); + if (avr <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "ReleaseJob: SELinux failed to translate av perm \"write\" of security class \"file\""); + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("SELinux failed to translate av perm \"write\" of security class \"file\" while processing job #%d."), + jobid); + return; + } + + if( avc_has_perm(clisid, jsid, tclass, avr, &avcref, NULL) ) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "ReleaseJob: Refusing Job %d due to SE level", job->id); + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid); + return; + } + } /* * See if job is "held"... */ @@ -10185,7 +10394,11 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */ int port; /* Port portion of URI */ int event; /* Events? */ int check_jobs; /* Check jobs? */ - + security_id_t clisid; /* SELinux SID for the client */ + security_id_t jsid; /* SELinux SID for the job */ + struct avc_entry_ref avcref; /* Pointer to the access vector cache */ + security_class_t tclass; /* Object class for the SELinux check */ + access_vector_t avr; /* Access method being requested */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_job_attrs(%p[%d], %s)", con, con->number, uri->values[0].string.text); @@ -10254,6 +10467,52 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */ return; } + if (is_selinux_mls_enabled () ) + { + static int avc_initialized = 0; + if (! avc_initialized++) + { + if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, "check_context: unable avc_init"); + return ; + } + + } + cupsdLogMessage(CUPSD_LOG_DEBUG2, "client context: %s", con->scon); + avc_context_to_sid(con->scon, &clisid); + avc_entry_ref_init(&avcref); + avc_context_to_sid(job->scon, &jsid); + + tclass = string_to_security_class("file"); + if (tclass <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "SetJobAttrs: SELinux failed to translate security class \"file\""); + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("SELinux failed to translate security class \"file\" while processing job #%d."), + jobid); + return; + } + + avr = string_to_av_perm(tclass, "write"); + if (avr <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "SetJobAttrs: SELinux failed to translate av perm \"write\" of security class \"file\""); + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("SELinux failed to translate av perm \"write\" of security class \"file\" while processing job #%d."), + jobid); + return; + } + + if( avc_has_perm(clisid, jsid, tclass, avr, &avcref, NULL) ) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "SetJobAttrs: Refusing Job %d due to SE level", job->id); + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid); + return; + } + } /* * See if the job has been completed... */