implement adding/removing temporary authorizations
authorDavid Zeuthen <davidz@redhat.com>
Mon, 19 Jan 2009 23:34:40 +0000 (18:34 -0500)
committerDavid Zeuthen <davidz@redhat.com>
Mon, 19 Jan 2009 23:34:40 +0000 (18:34 -0500)
docs/man/polkit.xml
src/polkitbackend/polkitbackendlocalauthority.c
src/programs/polkit.c

index 38efe66..f2f2d2c 100644 (file)
       <command>polkit-1 grant</command>
       <arg choice="plain"><replaceable>identity</replaceable></arg>
       <arg choice="plain"><replaceable>action-id</replaceable></arg>
+      <arg><option>--subject <replaceable>subject</replaceable></option></arg>
     </cmdsynopsis>
 
     <cmdsynopsis>
       <command>polkit-1 revoke</command>
       <arg choice="plain"><replaceable>identity</replaceable></arg>
       <arg choice="plain"><replaceable>action-id</replaceable></arg>
+      <arg><option>--subject <replaceable>subject</replaceable></option></arg>
     </cmdsynopsis>
 
     <cmdsynopsis>
         <command>polkit-1 grant</command>
         <arg choice="plain"><replaceable>identity</replaceable></arg>
         <arg choice="plain"><replaceable>action-id</replaceable></arg>
+        <arg><option>--subject <replaceable>subject</replaceable></option></arg>
       </para>
       <para>
-        Grants an authorization to <replaceable>identity</replaceable> for <replaceable>action-id</replaceable>.
-        See <xref linkend="polkit-1-identity"/> for details about <replaceable>identity</replaceable>.
+        Grants an authorization to <replaceable>identity</replaceable> for <replaceable>action-id</replaceable>
+        optionally constraining its use for <replaceable>subject</replaceable>.
+        See <xref linkend="polkit-1-identity"/> for details about <replaceable>identity</replaceable>
+        and <xref linkend="polkit-1-subject"/> for details about <replaceable>subject</replaceable>.
       </para>
     </refsect2>
 
         <command>polkit-1 revoke</command>
         <arg choice="plain"><replaceable>identity</replaceable></arg>
         <arg choice="plain"><replaceable>action-id</replaceable></arg>
+        <arg><option>--subject <replaceable>subject</replaceable></option></arg>
       </para>
       <para>
-        Revokes an authorization from <replaceable>identity</replaceable> for <replaceable>action-id</replaceable>.
-        See <xref linkend="polkit-1-identity"/> for details about <replaceable>identity</replaceable>.
+        Revokes an authorization from <replaceable>identity</replaceable> for <replaceable>action-id</replaceable>
+        which, optionally, is constrained to <replaceable>subject</replaceable>.
+        See <xref linkend="polkit-1-identity"/> for details about <replaceable>identity</replaceable>
+        and <xref linkend="polkit-1-subject"/> for details about <replaceable>subject</replaceable>.
       </para>
     </refsect2>
 
index a9d000f..febbf0b 100644 (file)
@@ -59,6 +59,7 @@ static gboolean check_authorization_for_identity (PolkitBackendLocalAuthority *a
                                                   const gchar                 *action_id);
 
 static gboolean check_temporary_authorization_for_subject (PolkitBackendLocalAuthority *authority,
+                                                           PolkitIdentity              *identity,
                                                            PolkitSubject               *subject,
                                                            const gchar                 *action_id);
 
@@ -478,7 +479,7 @@ check_authorization_sync (PolkitBackendAuthority         *authority,
   /* TODO: first see if there's an implicit authorization for subject available */
 
   /* then see if there's a temporary authorization for the subject */
-  if (check_temporary_authorization_for_subject (local_authority, subject, action_id))
+  if (check_temporary_authorization_for_subject (local_authority, user_of_subject, subject, action_id))
     {
       g_debug (" is authorized (has temporary authorization)");
       result = POLKIT_AUTHORIZATION_RESULT_AUTHORIZED;
@@ -672,7 +673,11 @@ static AuthorizationStore  *authorization_store_new (PolkitIdentity *identity);
 static GList               *authorization_store_get_all_authorizations (AuthorizationStore *store);
 
 static PolkitAuthorization *authorization_store_find_permanent_authorization (AuthorizationStore *store,
-                                                                             const gchar *action_id);
+                                                                              const gchar *action_id);
+
+static PolkitAuthorization *authorization_store_find_temporary_authorization (AuthorizationStore *store,
+                                                                              PolkitSubject *subject,
+                                                                              const gchar *action_id);
 
 static gboolean             authorization_store_add_authorization (AuthorizationStore   *store,
                                                                    PolkitAuthorization  *authorization,
@@ -897,6 +902,37 @@ authorization_store_find_permanent_authorization (AuthorizationStore *store,
   return ret;
 }
 
+static PolkitAuthorization *
+authorization_store_find_temporary_authorization (AuthorizationStore *store,
+                                                  PolkitSubject *subject,
+                                                  const gchar *action_id)
+{
+  GList *l;
+  PolkitAuthorization *ret;
+
+  ret = NULL;
+
+  for (l = store->temporary_authorizations; l != NULL; l = l->next)
+    {
+      PolkitAuthorization *authorization = POLKIT_AUTHORIZATION (l->data);
+      const gchar *authorization_action_id;
+      PolkitSubject *authorization_subject;
+
+      authorization_action_id = polkit_authorization_get_action_id (authorization);
+      authorization_subject = polkit_authorization_get_subject (authorization);
+
+      if (strcmp (authorization_action_id, action_id) == 0 &&
+          polkit_subject_equal (authorization_subject, subject))
+        {
+          ret = authorization;
+          goto out;
+        }
+    }
+
+ out:
+  return ret;
+}
+
 static gboolean
 authorization_store_add_authorization (AuthorizationStore   *store,
                                        PolkitAuthorization  *authorization,
@@ -913,11 +949,27 @@ authorization_store_add_authorization (AuthorizationStore   *store,
 
   if (subject != NULL)
     {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "Temporary authorizations not yet implemented");
-      goto out;
+      /* check if authorization is already present */
+      if (authorization_store_find_temporary_authorization (store, subject, action_id) != NULL)
+        {
+          gchar *subject_str;
+
+          subject_str = polkit_subject_to_string (subject);
+
+          g_set_error (error,
+                       POLKIT_ERROR,
+                       POLKIT_ERROR_FAILED,
+                       "Cannot add authorization. Identity already has an authorization for %s for the subject %s",
+                       action_id,
+                       subject_str);
+
+          g_free (subject_str);
+          goto out;
+        }
+
+      store->temporary_authorizations = g_list_prepend (store->temporary_authorizations, g_object_ref (authorization));
+
+      ret = TRUE;
     }
   else
     {
@@ -956,6 +1008,7 @@ authorization_store_remove_authorization (AuthorizationStore   *store,
   gboolean ret;
   PolkitSubject *subject;
   const gchar *action_id;
+  PolkitAuthorization *target;
 
   ret = FALSE;
 
@@ -964,15 +1017,32 @@ authorization_store_remove_authorization (AuthorizationStore   *store,
 
   if (subject != NULL)
     {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "Temporary authorizations not yet implemented");
+
+      target = authorization_store_find_temporary_authorization (store, subject, action_id);
+
+      if (target == NULL)
+        {
+          gchar *subject_str;
+
+          subject_str = polkit_subject_to_string (subject);
+
+          g_set_error (error,
+                       POLKIT_ERROR,
+                       POLKIT_ERROR_FAILED,
+                       "Cannot remove authorization. Identity doesn't has an authorization for %s constrained to the subject %s", action_id, subject_str);
+
+          g_free (subject_str);
+          goto out;
+        }
+
+      store->temporary_authorizations = g_list_remove (store->temporary_authorizations, target);
+
+      ret = TRUE;
+
       goto out;
     }
   else
     {
-      PolkitAuthorization *target;
       GList *old_list;
 
       target = authorization_store_find_permanent_authorization (store, action_id);
@@ -1058,11 +1128,23 @@ check_authorization_for_identity (PolkitBackendLocalAuthority *authority,
 
 static gboolean
 check_temporary_authorization_for_subject (PolkitBackendLocalAuthority *authority,
+                                           PolkitIdentity              *identity,
                                            PolkitSubject               *subject,
                                            const gchar                 *action_id)
 {
-  /* TODO */
-  return FALSE;
+  AuthorizationStore *store;
+  gboolean result;
+
+  result = FALSE;
+
+  store = get_authorization_store_for_identity (authority, identity);
+  if (store == NULL)
+    goto out;
+
+  result = (authorization_store_find_temporary_authorization (store, subject, action_id) != NULL);
+
+ out:
+  return result;
 }
 
 static GList *
index 83c3313..ce730fb 100644 (file)
@@ -175,7 +175,7 @@ main (int argc, char *argv[])
               goto out;
             }
 
-          action_id = g_strdup (argv[n++]);
+          action_id = g_strdup (argv[n]);
         }
       else if (strcmp (argv[n], "grant") == 0)
         {
@@ -203,7 +203,7 @@ main (int argc, char *argv[])
               goto out;
             }
 
-          action_id = g_strdup (argv[n++]);
+          action_id = g_strdup (argv[n]);
         }
       else if (strcmp (argv[n], "revoke") == 0)
         {
@@ -231,7 +231,24 @@ main (int argc, char *argv[])
               goto out;
             }
 
-          action_id = g_strdup (argv[n++]);
+          action_id = g_strdup (argv[n]);
+        }
+      else if (strcmp (argv[n], "--subject") == 0)
+        {
+          n++;
+          if (n >= argc)
+            {
+              usage (argc, argv);
+              goto out;
+            }
+
+          subject = polkit_subject_from_string (argv[n], &error);
+          if (subject == NULL)
+            {
+              g_printerr ("Error parsing subject: %s\n", error->message);
+              g_error_free (error);
+              goto out;
+            }
         }
       else if (strcmp (argv[n], "--help") == 0)
         {
@@ -779,9 +796,27 @@ list_explicit_authorizations (void)
 
       action_id = polkit_authorization_get_action_id (authorization);
 
-      /* TODO: verbose */
+      if (opt_verbose)
+        {
+          gchar *constrain_str;
+          PolkitSubject *subject;
 
-      g_print ("%s\n", action_id);
+          subject = polkit_authorization_get_subject (authorization);
+          if (subject != NULL)
+            constrain_str = polkit_subject_to_string (subject);
+          else
+            constrain_str = g_strdup ("<nothing>");
+
+          g_print ("%s:\n", action_id);
+          g_print ("  constrained to: %s\n", constrain_str);
+          g_print ("\n");
+
+          g_free (constrain_str);
+        }
+      else
+        {
+          g_print ("%s\n", action_id);
+        }
     }
 
   g_list_foreach (authorizations, (GFunc) g_object_unref, NULL);
@@ -806,7 +841,7 @@ do_grant (void)
   ret = FALSE;
 
   authorization = polkit_authorization_new (action_id,
-                                            NULL, /* TODO: handle subject */
+                                            subject,
                                             FALSE); /* TODO: handle negative */
 
   if (!polkit_authority_add_authorization_sync (authority,
@@ -842,7 +877,7 @@ do_revoke (void)
   ret = FALSE;
 
   authorization = polkit_authorization_new (action_id,
-                                            NULL, /* TODO: handle subject */
+                                            subject,
                                             FALSE); /* TODO: handle negative */
 
   if (!polkit_authority_remove_authorization_sync (authority,