From bc1a7ab9621dc2deb3f5de4d09364027fddcf252 Mon Sep 17 00:00:00 2001 From: mkasik Date: Wed, 28 Jan 2009 12:08:31 +0000 Subject: [PATCH] - Add functions for handling jobs (JobRestart, JobCancel, JobSetHoldUntil) --- cups-pk-helper.spec | 7 +- pk_jobs.patch | 402 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 pk_jobs.patch diff --git a/cups-pk-helper.spec b/cups-pk-helper.spec index 6217582..5e9fdac 100644 --- a/cups-pk-helper.spec +++ b/cups-pk-helper.spec @@ -1,6 +1,6 @@ Name: cups-pk-helper Version: 0.0.3 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A helper that makes system-config-printer use PolicyKit Group: System Environment/Base @@ -10,6 +10,7 @@ Source0: http://www.vuntz.net/download/cups-pk-helper/cups-pk-helper-%{ve Patch0: dependencies.patch Patch1: pk_order.patch +Patch2: pk_jobs.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -34,6 +35,7 @@ interfaces available under control of PolicyKit. %patch0 -p0 -b .dependencies %patch1 -p0 -b .pk-order +%patch2 -p0 -b .pk-jobs %build %configure @@ -60,6 +62,9 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Tue Jan 28 2009 Marek Kasik 0.0.3-3 +- Add functions for handling jobs (JobRestart, JobCancel, JobSetHoldUntil) + * Tue Jan 26 2009 Marek Kasik 0.0.3-2 - Add handling of file:/ protocol - Change order of checked policies so the PolicyKit asks only for diff --git a/pk_jobs.patch b/pk_jobs.patch new file mode 100644 index 0000000..cab48a3 --- /dev/null +++ b/pk_jobs.patch @@ -0,0 +1,402 @@ +--- src/cups.c 2009-01-28 12:51:49.000000000 +0100 ++++ src/cups.c 2009-01-28 10:59:36.000000000 +0100 +@@ -381,6 +381,18 @@ _cph_cups_add_class_uri (ipp_t *req + } + + static void ++_cph_cups_add_job_uri (ipp_t *request, ++ gint job_id) ++{ ++ char uri[HTTP_MAX_URI + 1]; ++ ++ g_snprintf (uri, sizeof (uri), ++ "ipp://localhost/jobs/%d", job_id); ++ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, ++ "job-uri", NULL, uri); ++} ++ ++static void + _cph_cups_set_internal_status (CphCups *cups, + const char *status) + { +@@ -541,6 +553,41 @@ _cph_cups_send_new_printer_class_request + return _cph_cups_send_request (cups, request, CPH_RESOURCE_ADMIN); + } + ++static gboolean ++_cph_cups_send_new_simple_job_request (CphCups *cups, ++ ipp_op_t op, ++ gint job_id, ++ CphResource resource) ++{ ++ ipp_t *request; ++ ++ request = ippNewRequest (op); ++ _cph_cups_add_job_uri (request, job_id); ++ ++ return _cph_cups_send_request (cups, request, resource); ++} ++ ++static gboolean ++_cph_cups_send_new_job_attributes_request (CphCups *cups, ++ gint job_id, ++ const char *name, ++ const char *value, ++ CphResource resource) ++{ ++ cups_option_t *options = NULL; ++ ipp_t *request; ++ gint num_options = 0; ++ ++ request = ippNewRequest (IPP_SET_JOB_ATTRIBUTES); ++ _cph_cups_add_job_uri (request, job_id); ++ ++ num_options = cupsAddOption (name, value, ++ num_options, &options); ++ cupsEncodeOptions (request, num_options, options); ++ ++ return _cph_cups_send_request (cups, request, resource); ++} ++ + static int + _cph_cups_class_has_printer (CphCups *cups, + const char *class_name, +@@ -1581,6 +1628,42 @@ cph_cups_server_set_settings (CphCups + return TRUE; + } + ++gboolean ++cph_cups_job_cancel (CphCups *cups, ++ gint job_id) ++{ ++ g_return_val_if_fail (CPH_IS_CUPS (cups), FALSE); ++ ++ return _cph_cups_send_new_simple_job_request (cups, IPP_CANCEL_JOB, ++ job_id, ++ CPH_RESOURCE_ADMIN); ++} ++ ++gboolean ++cph_cups_job_restart (CphCups *cups, ++ gint job_id) ++{ ++ g_return_val_if_fail (CPH_IS_CUPS (cups), FALSE); ++ ++ return _cph_cups_send_new_simple_job_request (cups, IPP_RESTART_JOB, ++ job_id, ++ CPH_RESOURCE_ADMIN); ++} ++ ++gboolean ++cph_cups_job_set_hold_until (CphCups *cups, ++ gint job_id, ++ const char *job_hold_until) ++{ ++ g_return_val_if_fail (CPH_IS_CUPS (cups), FALSE); ++ ++ return _cph_cups_send_new_job_attributes_request (cups, ++ job_id, ++ "job-hold-until", ++ job_hold_until, ++ CPH_RESOURCE_ADMIN); ++} ++ + /****************************************************** + * Non-object functions + ******************************************************/ +@@ -1647,3 +1730,28 @@ cph_cups_is_printer_uri_local (const cha + /* we don't know, so we assume it's not local */ + return FALSE; + } ++ ++gboolean ++cph_cups_is_job_owner (CphCups *cups, ++ gint job_id, ++ const char *user) ++{ ++ cups_job_t *jobs; ++ gboolean user_job = FALSE; ++ gint num_jobs = 0; ++ gint i; ++ ++ g_return_val_if_fail (CPH_IS_CUPS (cups), FALSE); ++ ++ if (user == NULL) ++ return FALSE; ++ ++ num_jobs = cupsGetJobs2 (cups->priv->connection, &jobs, NULL, 0, 0); ++ ++ for (i = 0; i < num_jobs; i++) { ++ if (jobs[i].id == job_id && g_strcmp0 (jobs[i].user, user) == 0) ++ user_job = TRUE; ++ } ++ ++ return user_job; ++} +--- src/cups.h 2008-11-21 01:50:42.000000000 +0100 ++++ src/cups.h 2009-01-27 17:33:00.000000000 +0100 +@@ -160,6 +160,20 @@ gboolean cph_cups_is_printer_local (CphC + + gboolean cph_cups_is_printer_uri_local (const char *uri); + ++gboolean cph_cups_job_cancel (CphCups *cups, ++ gint job_id); ++ ++gboolean cph_cups_job_restart (CphCups *cups, ++ gint job_id); ++ ++gboolean cph_cups_job_set_hold_until (CphCups *cups, ++ gint job_id, ++ const char *job_hold_until); ++ ++gboolean cph_cups_is_job_owner (CphCups *cups, ++ gint job_id, ++ const char *user); ++ + G_END_DECLS + + #endif /* CPH_CUPS_H */ +--- src/cups-pk-helper-mechanism.c 2009-01-28 12:51:49.000000000 +0100 ++++ src/cups-pk-helper-mechanism.c 2009-01-28 11:39:16.000000000 +0100 +@@ -47,6 +47,10 @@ + + #include + ++#include ++ ++#include ++ + #include "cups-pk-helper-mechanism.h" + #include "cups-pk-helper-mechanism-glue.h" + #include "cups.h" +@@ -1011,3 +1015,116 @@ cph_mechanism_server_set_settings (CphMe + + return TRUE; + } ++ ++gchar * ++cph_mechanism_get_callers_user_name (CphMechanism *mechanism, ++ DBusGMethodInvocation *context) ++{ ++ unsigned long sender_uid; ++ struct passwd *password_entry; ++ const gchar *sender; ++ DBusError dbus_error; ++ gchar *user_name = NULL; ++ ++ sender = dbus_g_method_get_sender (context); ++ dbus_error_init (&dbus_error); ++ sender_uid = dbus_bus_get_unix_user (dbus_g_connection_get_connection (mechanism->priv->system_bus_connection), sender, &dbus_error); ++ password_entry = getpwuid ((uid_t) sender_uid); ++ ++ if (password_entry != NULL) { ++ user_name = g_strdup(password_entry->pw_name); ++ } ++ ++ return user_name; ++} ++ ++gboolean ++cph_mechanism_job_cancel (CphMechanism *mechanism, ++ gint id, ++ DBusGMethodInvocation *context) ++{ ++ gboolean ret; ++ gboolean callers_job = FALSE; ++ char *user_name = NULL; ++ ++ reset_killtimer (mechanism); ++ ++ user_name = cph_mechanism_get_callers_user_name (mechanism, context); ++ callers_job = cph_cups_is_job_owner (mechanism->priv->cups, id, user_name); ++ g_free (user_name); ++ ++ if (callers_job) { ++ if (!_check_polkit_for_action (mechanism, context, "job-cancel")) ++ return FALSE; ++ } ++ else { ++ if (!_check_polkit_for_action (mechanism, context, "job-cancel-another-owner")) ++ return FALSE; ++ } ++ ++ ret = cph_cups_job_cancel (mechanism->priv->cups, id); ++ _cph_mechanism_return_error (mechanism, context, !ret); ++ ++ return TRUE; ++} ++ ++gboolean ++cph_mechanism_job_restart (CphMechanism *mechanism, ++ gint id, ++ DBusGMethodInvocation *context) ++{ ++ gboolean ret; ++ gboolean callers_job = FALSE; ++ char *user_name = NULL; ++ ++ reset_killtimer (mechanism); ++ ++ user_name = cph_mechanism_get_callers_user_name (mechanism, context); ++ callers_job = cph_cups_is_job_owner (mechanism->priv->cups, id, user_name); ++ g_free (user_name); ++ ++ if (callers_job) { ++ if (!_check_polkit_for_action (mechanism, context, "job-restart")) ++ return FALSE; ++ } ++ else { ++ if (!_check_polkit_for_action (mechanism, context, "job-restart-another-owner")) ++ return FALSE; ++ } ++ ++ ret = cph_cups_job_restart (mechanism->priv->cups, id); ++ _cph_mechanism_return_error (mechanism, context, !ret); ++ ++ return TRUE; ++} ++ ++gboolean ++cph_mechanism_job_set_hold_until (CphMechanism *mechanism, ++ gint id, ++ const char *job_hold_until, ++ DBusGMethodInvocation *context) ++{ ++ gboolean ret; ++ gboolean callers_job = FALSE; ++ char *user_name = NULL; ++ ++ reset_killtimer (mechanism); ++ ++ user_name = cph_mechanism_get_callers_user_name (mechanism, context); ++ callers_job = cph_cups_is_job_owner (mechanism->priv->cups, id, user_name); ++ g_free (user_name); ++ ++ if (callers_job) { ++ if (!_check_polkit_for_action (mechanism, context, "job-set-hold-until")) ++ return FALSE; ++ } ++ else { ++ if (!_check_polkit_for_action (mechanism, context, "job-set-hold-until-another-owner")) ++ return FALSE; ++ } ++ ++ ret = cph_cups_job_set_hold_until (mechanism->priv->cups, id, job_hold_until); ++ _cph_mechanism_return_error (mechanism, context, !ret); ++ ++ return TRUE; ++} +--- src/cups-pk-helper-mechanism.h 2008-11-21 01:57:03.000000000 +0100 ++++ src/cups-pk-helper-mechanism.h 2009-01-27 17:31:20.000000000 +0100 +@@ -220,6 +220,22 @@ cph_mechanism_server_set_settings (CphMe + GHashTable *settings, + DBusGMethodInvocation *context); + ++gboolean ++cph_mechanism_job_cancel (CphMechanism *mechanism, ++ gint id, ++ DBusGMethodInvocation *context); ++ ++gboolean ++cph_mechanism_job_restart (CphMechanism *mechanism, ++ gint id, ++ DBusGMethodInvocation *context); ++ ++gboolean ++cph_mechanism_job_set_hold_until (CphMechanism *mechanism, ++ gint id, ++ const char *job_hold_until, ++ DBusGMethodInvocation *context); ++ + G_END_DECLS + + #endif /* CPH_MECHANISM_H */ +--- src/cups-pk-helper-mechanism.xml 2008-11-21 01:55:52.000000000 +0100 ++++ src/cups-pk-helper-mechanism.xml 2009-01-27 17:26:57.000000000 +0100 +@@ -174,5 +174,23 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + +--- src/org.opensuse.cupspkhelper.mechanism.policy.in 2008-11-21 00:58:16.000000000 +0100 ++++ src/org.opensuse.cupspkhelper.mechanism.policy.in 2009-01-28 12:47:49.000000000 +0100 +@@ -68,6 +68,60 @@ + + + ++ ++ <_description>Cancel a job ++ <_message>Privileges are required to cancel a job. ++ ++ no ++ auth_self ++ ++ ++ ++ ++ <_description>Cancel a job owned by another user ++ <_message>Privileges are required to cancel a job owned by another user. ++ ++ no ++ auth_admin ++ ++ ++ ++ ++ <_description>Restart a job ++ <_message>Privileges are required to restart a job. ++ ++ no ++ yes ++ ++ ++ ++ ++ <_description>Restart a job owned by another user ++ <_message>Privileges are required to restart a job owned by another user. ++ ++ no ++ auth_admin ++ ++ ++ ++ ++ <_description>Set hold-until time of a job ++ <_message>Privileges are required to set hold-until time of a job. ++ ++ no ++ yes ++ ++ ++ ++ ++ <_description>Set hold-until time of a job owned by another ++ <_message>Privileges are required to set hold-until time of a job owned by another user. ++ ++ no ++ auth_admin ++ ++ ++ + + + <_description>Add/Remove/Edit a printer