403 lines
14 KiB
Diff
403 lines
14 KiB
Diff
--- 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 <polkit-dbus/polkit-dbus.h>
|
|
|
|
+#include <cups/cups.h>
|
|
+
|
|
+#include <pwd.h>
|
|
+
|
|
#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 @@
|
|
<arg name="error" direction="out" type="s"/>
|
|
</method>
|
|
|
|
+ <method name="JobCancel">
|
|
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
|
+ <arg name="jobid" direction="in" type="i"/>
|
|
+ <arg name="error" direction="out" type="s"/>
|
|
+ </method>
|
|
+
|
|
+ <method name="JobRestart">
|
|
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
|
+ <arg name="jobid" direction="in" type="i"/>
|
|
+ <arg name="error" direction="out" type="s"/>
|
|
+ </method>
|
|
+
|
|
+ <method name="JobSetHoldUntil">
|
|
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
|
+ <arg name="jobid" direction="in" type="i"/>
|
|
+ <arg name="job_hold_until" direction="in" type="s"/>
|
|
+ <arg name="error" direction="out" type="s"/>
|
|
+ </method>
|
|
</interface>
|
|
</node>
|
|
--- 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 @@
|
|
</defaults>
|
|
</action>
|
|
|
|
+ <action id="org.opensuse.cupspkhelper.mechanism.job-cancel">
|
|
+ <_description>Cancel a job</_description>
|
|
+ <_message>Privileges are required to cancel a job.</_message>
|
|
+ <defaults>
|
|
+ <allow_inactive>no</allow_inactive>
|
|
+ <allow_active>auth_self</allow_active>
|
|
+ </defaults>
|
|
+ </action>
|
|
+
|
|
+ <action id="org.opensuse.cupspkhelper.mechanism.job-cancel-another-owner">
|
|
+ <_description>Cancel a job owned by another user</_description>
|
|
+ <_message>Privileges are required to cancel a job owned by another user.</_message>
|
|
+ <defaults>
|
|
+ <allow_inactive>no</allow_inactive>
|
|
+ <allow_active>auth_admin</allow_active>
|
|
+ </defaults>
|
|
+ </action>
|
|
+
|
|
+ <action id="org.opensuse.cupspkhelper.mechanism.job-restart">
|
|
+ <_description>Restart a job</_description>
|
|
+ <_message>Privileges are required to restart a job.</_message>
|
|
+ <defaults>
|
|
+ <allow_inactive>no</allow_inactive>
|
|
+ <allow_active>yes</allow_active>
|
|
+ </defaults>
|
|
+ </action>
|
|
+
|
|
+ <action id="org.opensuse.cupspkhelper.mechanism.job-restart-another-owner">
|
|
+ <_description>Restart a job owned by another user</_description>
|
|
+ <_message>Privileges are required to restart a job owned by another user.</_message>
|
|
+ <defaults>
|
|
+ <allow_inactive>no</allow_inactive>
|
|
+ <allow_active>auth_admin</allow_active>
|
|
+ </defaults>
|
|
+ </action>
|
|
+
|
|
+ <action id="org.opensuse.cupspkhelper.mechanism.job-set-hold-until">
|
|
+ <_description>Set hold-until time of a job</_description>
|
|
+ <_message>Privileges are required to set hold-until time of a job.</_message>
|
|
+ <defaults>
|
|
+ <allow_inactive>no</allow_inactive>
|
|
+ <allow_active>yes</allow_active>
|
|
+ </defaults>
|
|
+ </action>
|
|
+
|
|
+ <action id="org.opensuse.cupspkhelper.mechanism.job-set-hold-until-another-owner">
|
|
+ <_description>Set hold-until time of a job owned by another</_description>
|
|
+ <_message>Privileges are required to set hold-until time of a job owned by another user.</_message>
|
|
+ <defaults>
|
|
+ <allow_inactive>no</allow_inactive>
|
|
+ <allow_active>auth_admin</allow_active>
|
|
+ </defaults>
|
|
+ </action>
|
|
+
|
|
<!-- Deprecated -->
|
|
<action id="org.opensuse.cupspkhelper.mechanism.printeraddremove">
|
|
<_description>Add/Remove/Edit a printer</_description>
|