summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/org.freedesktop.PolicyKit1.Authority.xml3
-rw-r--r--src/polkit/polkiterror.h8
-rw-r--r--src/polkit/polkitsubject.c4
-rw-r--r--src/polkitbackend/polkitbackendlocalauthority.c174
-rw-r--r--src/polkitbackend/polkitbackendsessionmonitor.c89
-rw-r--r--src/polkitbackend/polkitbackendsessionmonitor.h4
6 files changed, 270 insertions, 12 deletions
diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml
index 75d9586..76f68d6 100644
--- a/data/org.freedesktop.PolicyKit1.Authority.xml
+++ b/data/org.freedesktop.PolicyKit1.Authority.xml
@@ -65,6 +65,9 @@
<annotation name="org.gtk.EggDBus.ErrorDomain.Member" value="org.freedesktop.PolicyKit1.Error.NotSupported">
<annotation name="org.gtk.EggDBus.DocString" value="Operation is not supported"/>
</annotation>
+ <annotation name="org.gtk.EggDBus.ErrorDomain.Member" value="org.freedesktop.PolicyKit1.Error.NotAuthorized">
+ <annotation name="org.gtk.EggDBus.DocString" value="Not authorized to perform operation"/>
+ </annotation>
</annotation>
<!-- An enumeration for results of CheckClaim() (TODO: implement this method) -->
diff --git a/src/polkit/polkiterror.h b/src/polkit/polkiterror.h
index 5dd21dc..9ef2955 100644
--- a/src/polkit/polkiterror.h
+++ b/src/polkit/polkiterror.h
@@ -42,15 +42,17 @@ GType polkit_error_get_type (void) G_GNUC_CONST;
/**
* PolkitError:
- * @POLKIT_ERROR_FAILED: The operation failed
- * @POLKIT_ERROR_NOT_SUPPORTED: Operation is not supported
+ * @POLKIT_ERROR_FAILED: The operation failed.
+ * @POLKIT_ERROR_NOT_SUPPORTED: Operation is not supported.
+ * @POLKIT_ERROR_NOT_AUTHORIZED: Not authorized to perform operation.
*
- * Errors when using PolicyKit.
+ * Possible error when using PolicyKit.
*/
typedef enum
{
POLKIT_ERROR_FAILED = 0,
POLKIT_ERROR_NOT_SUPPORTED = 1,
+ POLKIT_ERROR_NOT_AUTHORIZED = 2,
} PolkitError;
G_END_DECLS
diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c
index d7c5434..e34bddc 100644
--- a/src/polkit/polkitsubject.c
+++ b/src/polkit/polkitsubject.c
@@ -140,6 +140,10 @@ polkit_subject_from_string (const gchar *str,
}
}
}
+ else if (g_str_has_prefix (str, "unix-session:"))
+ {
+ subject = polkit_unix_session_new (str + sizeof "unix-session:" - 1);
+ }
else if (g_str_has_prefix (str, "system-bus-name:"))
{
subject = polkit_system_bus_name_new (str + sizeof "system-bus-name:" - 1);
diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c
index db49f99..f6fda0b 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.c
+++ b/src/polkitbackend/polkitbackendlocalauthority.c
@@ -55,6 +55,10 @@ static void polkit_backend_local_authority_check_claim (PolkitBackendAuth
PolkitAuthorizationClaim *claim,
PolkitBackendPendingCall *pending_call);
+static PolkitAuthorizationResult check_claim_sync (PolkitBackendAuthority *authority,
+ PolkitAuthorizationClaim *claim,
+ GError **error);
+
G_DEFINE_TYPE (PolkitBackendLocalAuthority, polkit_backend_local_authority, POLKIT_BACKEND_TYPE_AUTHORITY);
#define POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_BACKEND_TYPE_LOCAL_AUTHORITY, PolkitBackendLocalAuthorityPrivate))
@@ -256,11 +260,32 @@ polkit_backend_local_authority_check_claim (PolkitBackendAuthority *authority,
PolkitAuthorizationClaim *claim,
PolkitBackendPendingCall *pending_call)
{
- gchar *inquirer_str;
- gchar *subject_str;
+ PolkitBackendLocalAuthority *local_authority;
+ PolkitBackendLocalAuthorityPrivate *priv;
PolkitSubject *inquirer;
PolkitSubject *subject;
+ gchar *inquirer_str;
+ gchar *subject_str;
+ PolkitSubject *user_of_inquirer;
+ PolkitSubject *user_of_subject;
+ gchar *user_of_inquirer_str;
+ gchar *user_of_subject_str;
+ PolkitAuthorizationResult result;
const gchar *action_id;
+ GError *error;
+
+ local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
+ priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
+
+ error = NULL;
+ inquirer = NULL;
+ subject = NULL;
+ inquirer_str = NULL;
+ subject_str = NULL;
+ user_of_inquirer = NULL;
+ user_of_subject = NULL;
+ user_of_inquirer_str = NULL;
+ user_of_subject_str = NULL;
inquirer = polkit_backend_pending_call_get_caller (pending_call);
subject = polkit_authorization_claim_get_subject (claim);
@@ -274,17 +299,148 @@ polkit_backend_local_authority_check_claim (PolkitBackendAuthority *authority,
subject_str,
action_id);
- /* TODO: temp */
- polkit_backend_authority_check_claim_finish (pending_call, POLKIT_AUTHORIZATION_RESULT_AUTHORIZED);
+ user_of_inquirer = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
+ inquirer,
+ &error);
+ if (error != NULL)
+ {
+ polkit_backend_pending_call_return_gerror (pending_call, error);
+ g_error_free (error);
+ goto out;
+ }
+
+ user_of_inquirer_str = polkit_subject_to_string (user_of_inquirer);
+ g_debug (" user of inquirer is %s", user_of_inquirer_str);
+
+ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
+ subject,
+ &error);
+ if (error != NULL)
+ {
+ polkit_backend_pending_call_return_gerror (pending_call, error);
+ g_error_free (error);
+ goto out;
+ }
+
+ user_of_subject_str = polkit_subject_to_string (user_of_subject);
+ g_debug (" user of subject is %s", user_of_subject_str);
+
+ /* if the user of the inquirer and the user of the subject isn't the same, then
+ * the org.freedesktop.policykit.read authorization is required for the inquirer
+ */
+ if (!polkit_subject_equal (user_of_inquirer, user_of_subject))
+ {
+ PolkitAuthorizationClaim *read_claim;
+
+ read_claim = polkit_authorization_claim_new (user_of_inquirer, "org.freedesktop.policykit.read");
+ result = check_claim_sync (authority, read_claim, &error);
+ g_object_unref (read_claim);
+
+ if (error != NULL)
+ {
+ polkit_backend_pending_call_return_gerror (pending_call, error);
+ g_error_free (error);
+ goto out;
+ }
+ else if (result != POLKIT_AUTHORIZATION_RESULT_AUTHORIZED)
+ {
+ polkit_backend_pending_call_return_error (pending_call,
+ POLKIT_ERROR,
+ POLKIT_ERROR_NOT_AUTHORIZED,
+ "%s is not authorized to know about authorizations for %s (requires org.freedesktop.policykit.read authorization)",
+ user_of_inquirer_str,
+ subject_str);
+ goto out;
+ }
+ }
+
+ result = check_claim_sync (authority, claim, &error);
+ if (error != NULL)
+ {
+ polkit_backend_pending_call_return_gerror (pending_call, error);
+ g_error_free (error);
+ }
+ else
+ {
+ polkit_backend_authority_check_claim_finish (pending_call, result);
+ }
+
+ out:
+
+ if (user_of_inquirer != NULL)
+ g_object_unref (user_of_inquirer);
+
+ if (user_of_subject != NULL)
+ g_object_unref (user_of_subject);
+
+ g_free (inquirer_str);
+ g_free (subject_str);
+ g_free (user_of_inquirer_str);
+ g_free (user_of_subject_str);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static PolkitAuthorizationResult
+check_claim_sync (PolkitBackendAuthority *authority,
+ PolkitAuthorizationClaim *claim,
+ GError **error)
+{
+ PolkitBackendLocalAuthority *local_authority;
+ PolkitBackendLocalAuthorityPrivate *priv;
+ PolkitAuthorizationResult result;
+ PolkitSubject *subject;
+ PolkitSubject *user_of_subject;
+ gchar *subject_str;
+ const gchar *action_id;
+
+ local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
+ priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
+
+ result = POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED;
+ user_of_subject = NULL;
+ subject_str = NULL;
+
+ subject = polkit_authorization_claim_get_subject (claim);
+ action_id = polkit_authorization_claim_get_action_id (claim);
+
+ subject_str = polkit_subject_to_string (subject);
+
+ g_debug ("checking whether %s is authorized for %s",
+ subject_str,
+ action_id);
+
+ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
+ subject,
+ error);
+ if (user_of_subject == NULL)
+ goto out;
+
+ if (POLKIT_IS_UNIX_USER (user_of_subject) && polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_subject)) == 0)
+ {
+ /* uid 0, root, is _always_ authorized for anything */
+ result = POLKIT_AUTHORIZATION_RESULT_AUTHORIZED;
+ goto out;
+ }
#if 0
- polkit_backend_pending_call_return_error (pending_call,
- POLKIT_ERROR,
- POLKIT_ERROR_NOT_SUPPORTED,
- "Not implemented");
+ g_set_error (error,
+ POLKIT_ERROR,
+ POLKIT_ERROR_NOT_SUPPORTED,
+ "Not implemented (subject=%s action_id=%s)",
+ subject_str, action_id);
#endif
- g_free (inquirer_str);
+ /* TODO */
+ result = POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED;
+
+ out:
g_free (subject_str);
+
+ if (user_of_subject != NULL)
+ g_object_unref (user_of_subject);
+
+ return result;
}
+/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c
index 5284c20..8f9783d 100644
--- a/src/polkitbackend/polkitbackendsessionmonitor.c
+++ b/src/polkitbackend/polkitbackendsessionmonitor.c
@@ -333,6 +333,8 @@ get_sessions_foreach_cb (EggDBusHashMap *map,
return FALSE;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
GList *
polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monitor)
{
@@ -349,3 +351,90 @@ polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monito
return l;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * polkit_backend_session_monitor_get_user:
+ * @monitor: A #PolkitBackendSessionMonitor.
+ * @subject: A #PolkitSubject.
+ * @error: Return location for error.
+ *
+ * Gets the user corresponding to @subject or %NULL if no user exists.
+ *
+ * Returns: %NULL if @error is set otherwise a #PolkitUnixUser that should be freed with g_object_unref().
+ */
+PolkitSubject *
+polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor,
+ PolkitSubject *subject,
+ GError **error)
+{
+ PolkitSubject *user;
+ uid_t uid;
+
+ user = NULL;
+
+ if (POLKIT_IS_UNIX_USER (subject))
+ {
+ user = g_object_ref (subject);
+ }
+ else if (POLKIT_IS_UNIX_PROCESS (subject))
+ {
+ pid_t pid;
+
+ pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject));
+ uid = 500; /* TODO */
+
+ user = polkit_unix_user_new (uid);
+ }
+ else if (POLKIT_IS_UNIX_SESSION (subject))
+ {
+ const gchar *session_id;
+ EggDBusObjectProxy *session_object_proxy;
+ CkSession *session;
+
+ session_id = polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (subject));
+
+ session_object_proxy = egg_dbus_hash_map_lookup (monitor->session_object_path_to_object_proxy,
+ session_id);
+ if (session_object_proxy == NULL)
+ {
+ g_set_error (error,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "No ConsoleKit session with id %s",
+ session_id);
+ goto out;
+ }
+
+ session = CK_QUERY_INTERFACE_SESSION (session_object_proxy);
+
+ uid = (uid_t) ck_session_get_user (session);
+
+ user = polkit_unix_user_new (uid);
+ }
+ else if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
+ {
+ /* TODO: cache this stuff */
+ if (!egg_dbus_bus_get_connection_unix_user_sync (egg_dbus_connection_get_bus (monitor->system_bus),
+ EGG_DBUS_CALL_FLAGS_NONE,
+ polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject)),
+ &uid,
+ NULL,
+ error))
+ goto out;
+
+ user = polkit_unix_user_new (uid);
+ }
+ else
+ {
+ g_set_error (error,
+ POLKIT_ERROR,
+ POLKIT_ERROR_NOT_SUPPORTED,
+ "Cannot get user for subject of type %s",
+ g_type_name (G_TYPE_FROM_INSTANCE (subject)));
+ }
+
+ out:
+
+ return user;
+}
diff --git a/src/polkitbackend/polkitbackendsessionmonitor.h b/src/polkitbackend/polkitbackendsessionmonitor.h
index e5457bb..46ca247 100644
--- a/src/polkitbackend/polkitbackendsessionmonitor.h
+++ b/src/polkitbackend/polkitbackendsessionmonitor.h
@@ -47,6 +47,10 @@ GType polkit_backend_session_monitor_get_type (void)
PolkitBackendSessionMonitor *polkit_backend_session_monitor_new (void);
GList *polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monitor);
+PolkitSubject *polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor,
+ PolkitSubject *subject,
+ GError **error);
+
G_END_DECLS
#endif /* __POLKIT_BACKEND_SESSION_MONITOR_H */