Commit ffc99a26 authored by David Zeuthen's avatar David Zeuthen

Implement lockdown for the Local Authority implementation

parent 2a932ebb
...@@ -58,4 +58,15 @@ ...@@ -58,4 +58,15 @@
<allow_active>auth_admin</allow_active> <allow_active>auth_admin</allow_active>
</defaults> </defaults>
</action> </action>
<action id="org.freedesktop.policykit.localauthority.lockdown">
<_description>Configure lockdown on the Local Authority</_description>
<_message>Authentication is required to configure lock down policy</_message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/pklalockdown</annotate>
</action>
</policyconfig> </policyconfig>
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
</annotation> </annotation>
<annotation name="org.gtk.EggDBus.Struct.Member" value="Dict<String,String>:details"> <annotation name="org.gtk.EggDBus.Struct.Member" value="Dict<String,String>:details">
<annotation name="org.gtk.EggDBus.DocString" value="Details for the result or empty if not authorized. Known key/value-pairs include <literal>polkit.temporary_authorization_id</literal> (if the authorization is temporary, this is set to the opaque temporary authorization id) and <literal>polkit.retains_authorization_after_challenge</literal> (Set to a non-empty string if the authorization will be retained after authentication (if is_challenge is TRUE))."/> <annotation name="org.gtk.EggDBus.DocString" value="Details for the result or empty if not authorized. Known key/value-pairs include <literal>polkit.temporary_authorization_id</literal> (if the authorization is temporary, this is set to the opaque temporary authorization id), <literal>polkit.retains_authorization_after_challenge</literal> (Set to a non-empty string if the authorization will be retained after authentication (if is_challenge is TRUE)) and <literal>polkit.localauthority.lockdown</literal> (set to a non-empty string if the action is locked down via pklalockdown(1))."/>
</annotation> </annotation>
</annotation> </annotation>
......
...@@ -10,6 +10,7 @@ man_MANS = \ ...@@ -10,6 +10,7 @@ man_MANS = \
pkexec.1 \ pkexec.1 \
pkcheck.1 \ pkcheck.1 \
pkaction.1 \ pkaction.1 \
pklalockdown.1 \
$(NULL) $(NULL)
%.8 %.1 : %.xml %.8 %.1 : %.xml
...@@ -24,6 +25,7 @@ EXTRA_DIST = \ ...@@ -24,6 +25,7 @@ EXTRA_DIST = \
pkexec.xml \ pkexec.xml \
pkcheck.xml \ pkcheck.xml \
pkaction.xml \ pkaction.xml \
pklalockdown.xml \
$(NULL) $(NULL)
clean-local: clean-local:
......
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "../version.xml">
]>
<refentry id="pklalockdown.1" xmlns:xi="http://www.w3.org/2003/XInclude">
<refentryinfo>
<title>pklalockdown</title>
<date>May 2009</date>
<productname>polkit</productname>
</refentryinfo>
<refmeta>
<refentrytitle>pklalockdown</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="version"></refmiscinfo>
</refmeta>
<refnamediv>
<refname>pklalockdown</refname>
<refpurpose>Configure lockdown for the Local Authority</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>pklalockdown</command>
<arg><option>--version</option></arg>
<arg><option>--help</option></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>pklalockdown</command>
<arg choice="plain">
<option>--lockdown</option>
<replaceable>action</replaceable>
</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>pklalockdown</command>
<arg choice="plain">
<option>--remove-lockdown</option>
<replaceable>action</replaceable>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id="pklalockdown-description">
<title>DESCRIPTION</title>
<para>
<command>pklalockdown</command> is used to configure lockdown
for the Local Authority.
</para>
<para>
The effect of locking down an action is that administrator
authentication is always needed in order for subjects to acquire
the authorization for the action in question (and the subject
has to be in an active session on a local console). The obtained
authorization is temporary and as such typically expires five
minutes after being obtained.
</para>
<para>
To lock down <replaceable>action</replaceable> use the <option>--lockdown</option> option.
To remove a lockdown for <replaceable>action</replaceable> use the <option>--remove-lockdown</option> option.
</para>
</refsect1>
<refsect1 id="pklalockdown-required-auhtz">
<title>REQUIRED AUTHORIZATIONS</title>
<para>
The <emphasis>org.freedesktop.policykit.localauthority.lockdown</emphasis>
authorization is needed to add or remove lockdown. By default,
this authorization requires administrator authentication and
cannot be retained.
</para>
</refsect1>
<refsect1 id="pklalockdown-impl-details">
<title>IMPLEMENTATION DETAILS</title>
<para>
Lockdown is implemented through <filename>.pkla</filename>
files. Locked down actions supersede other most other Local
Authority configuration as the <filename>.pkla</filename> files
are placed
in <filename>/var/lib/polkit-1/localauthority90-mandatory.d</filename>.
<para>
</para>
Programs checking authorizations can check whether an action is
locked down via by checking
the <emphasis>polkit.localauthority.lockdown</emphasis> key/value pair in
the details of the authorization response.
</para>
</refsect1>
<refsect1 id="pklalockdown-return-values">
<title>RETURN VALUE</title>
<para>
On success <command>pklalockdown</command> returns 0. Otherwise a
non-zero value is returned and a diagnostic message is printed
on standard error.
</para>
</refsect1>
<refsect1 id="pklalockdown-author"><title>AUTHOR</title>
<para>
Written by David Zeuthen <email>davidz@redhat.com</email> with
a lot of help from many others.
</para>
</refsect1>
<refsect1 id="pklalockdown-bugs">
<title>BUGS</title>
<para>
Please send bug reports to either the distribution or the
polkit-devel mailing list,
see the link <ulink url="http://lists.freedesktop.org/mailman/listinfo/polkit-devel"/>
on how to subscribe.
</para>
</refsect1>
<refsect1 id="pklalockdown-see-also">
<title>SEE ALSO</title>
<para>
<citerefentry>
<refentrytitle>polkit</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>pkcheck</refentrytitle><manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>pklocalauthority</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>
...@@ -155,7 +155,7 @@ ...@@ -155,7 +155,7 @@
<para> <para>
Each group in a <filename>.pkla</filename> must have a name that Each group in a <filename>.pkla</filename> must have a name that
is unique within the file it belongs to. The following keys are is unique within the file it belongs to. The following keys are
required in each group are processed.
</para> </para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
...@@ -214,12 +214,23 @@ ...@@ -214,12 +214,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><emphasis>ReturnValue</emphasis></term>
<listitem>
<para>
A semi-colon separated list of key/value pairs (of the
form key=value) that are add to the details of
authorization result on positive matches.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
<para> <para>
All keys specified above are required except that only at least All keys specified above are required except that only at least
one one
of <emphasis>RequireAny</emphasis>, <emphasis>RequireInactive</emphasis> of <emphasis>RequireAny</emphasis>, <emphasis>RequireInactive</emphasis>
and <emphasis>RequireActive</emphasis> is present. and <emphasis>RequireActive</emphasis> is
present. The <emphasis>ReturnValue</emphasis> key is optional.
</para> </para>
</refsect1> </refsect1>
...@@ -240,8 +251,10 @@ ...@@ -240,8 +251,10 @@
authorization check matches the data from the authorization authorization check matches the data from the authorization
check, then the authorization result check, then the authorization result
from <emphasis>RequireAny</emphasis>, <emphasis>RequireInactive</emphasis> from <emphasis>RequireAny</emphasis>, <emphasis>RequireInactive</emphasis>
or <emphasis>RequireActive</emphasis> is used. Finally, the or <emphasis>RequireActive</emphasis> is used
authorization entries are consulted using the user identity. and <emphasis>ReturnValue</emphasis> is added to the
authorization result. Finally, the authorization entries are
consulted using the user identity in the same manner.
</para> </para>
<para> <para>
Note that processing continues even after a match. This allows Note that processing continues even after a match. This allows
......
...@@ -110,10 +110,11 @@ ...@@ -110,10 +110,11 @@
<title>Manual Pages</title> <title>Manual Pages</title>
<xi:include href="../man/polkit.xml"/> <xi:include href="../man/polkit.xml"/>
<xi:include href="../man/polkitd.xml"/> <xi:include href="../man/polkitd.xml"/>
<xi:include href="../man/pklocalauthority.xml"/>
<xi:include href="../man/pkcheck.xml"/> <xi:include href="../man/pkcheck.xml"/>
<xi:include href="../man/pkaction.xml"/> <xi:include href="../man/pkaction.xml"/>
<xi:include href="../man/pkexec.xml"/> <xi:include href="../man/pkexec.xml"/>
<xi:include href="../man/pklocalauthority.xml"/>
<xi:include href="../man/pklalockdown.xml"/>
</part> </part>
<chapter id="polkit-hierarchy"> <chapter id="polkit-hierarchy">
......
...@@ -64,6 +64,7 @@ polkit_authorization_result_get_is_authorized ...@@ -64,6 +64,7 @@ polkit_authorization_result_get_is_authorized
polkit_authorization_result_get_is_challenge polkit_authorization_result_get_is_challenge
polkit_authorization_result_get_retains_authorization polkit_authorization_result_get_retains_authorization
polkit_authorization_result_get_temporary_authorization_id polkit_authorization_result_get_temporary_authorization_id
polkit_authorization_result_get_local_authority_lock_down
polkit_authorization_result_get_details polkit_authorization_result_get_details
<SUBSECTION Standard> <SUBSECTION Standard>
PolkitAuthorizationResultClass PolkitAuthorizationResultClass
......
...@@ -276,3 +276,28 @@ polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationR ...@@ -276,3 +276,28 @@ polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationR
return ret; return ret;
} }
/**
* polkit_authorization_result_get_local_authority_lock_down:
* @result: A #PolkitAuthorizationResult.
*
* Gets whether the action is locked down in the Local Authority via pklalockdown(1).
*
* This method simply reads the value of the key/value pair in @details with the
* key <literal>polkit.localauthority.lockdown</literal>.
*
* Returns: %TRUE if the authorization is or will be temporary.
*/
gboolean
polkit_authorization_result_get_local_authority_lock_down (PolkitAuthorizationResult *result)
{
gboolean ret;
PolkitDetails *details;
ret = FALSE;
details = polkit_authorization_result_get_details (result);
if (details != NULL && polkit_details_lookup (details, "polkit.localauthority.lockdown") != NULL)
ret = TRUE;
return ret;
}
...@@ -52,6 +52,7 @@ gboolean polkit_authorization_result_get_is_authorized (P ...@@ -52,6 +52,7 @@ gboolean polkit_authorization_result_get_is_authorized (P
gboolean polkit_authorization_result_get_is_challenge (PolkitAuthorizationResult *result); gboolean polkit_authorization_result_get_is_challenge (PolkitAuthorizationResult *result);
gboolean polkit_authorization_result_get_retains_authorization (PolkitAuthorizationResult *result); gboolean polkit_authorization_result_get_retains_authorization (PolkitAuthorizationResult *result);
const gchar *polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationResult *result); const gchar *polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationResult *result);
gboolean polkit_authorization_result_get_local_authority_lock_down (PolkitAuthorizationResult *result);
/* ---------------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------------- */
......
...@@ -715,7 +715,8 @@ check_authorization_sync (PolkitBackendAuthority *authority, ...@@ -715,7 +715,8 @@ check_authorization_sync (PolkitBackendAuthority *authority,
session_is_active, session_is_active,
action_id, action_id,
details, details,
implicit_authorization); implicit_authorization,
result_details);
/* first see if there's an implicit authorization for subject available */ /* first see if there's an implicit authorization for subject available */
if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED) if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED)
...@@ -844,9 +845,12 @@ polkit_backend_interactive_authority_get_admin_identities (PolkitBackendInteract ...@@ -844,9 +845,12 @@ polkit_backend_interactive_authority_get_admin_identities (PolkitBackendInteract
* @action_id: The action we are checking an authorization for. * @action_id: The action we are checking an authorization for.
* @details: Details about the action. * @details: Details about the action.
* @implicit: A #PolkitImplicitAuthorization value computed from the policy file and @subject. * @implicit: A #PolkitImplicitAuthorization value computed from the policy file and @subject.
* @out_details: A #PolkitDetails object that will be return to @caller.
* *
* Checks whether @subject is authorized to perform the action * Checks whether @subject is authorized to perform the action
* specified by @action_id and @details. * specified by @action_id and @details. The implementation may
* append key/value pairs to @out_details to return extra information
* to @caller.
* *
* The default implementation of this method simply returns @implicit. * The default implementation of this method simply returns @implicit.
* *
...@@ -862,7 +866,8 @@ polkit_backend_interactive_authority_check_authorization_sync (PolkitBackendInte ...@@ -862,7 +866,8 @@ polkit_backend_interactive_authority_check_authorization_sync (PolkitBackendInte
gboolean subject_is_active, gboolean subject_is_active,
const gchar *action_id, const gchar *action_id,
PolkitDetails *details, PolkitDetails *details,
PolkitImplicitAuthorization implicit) PolkitImplicitAuthorization implicit,
PolkitDetails *out_details)
{ {
PolkitBackendInteractiveAuthorityClass *klass; PolkitBackendInteractiveAuthorityClass *klass;
PolkitImplicitAuthorization ret; PolkitImplicitAuthorization ret;
...@@ -883,7 +888,8 @@ polkit_backend_interactive_authority_check_authorization_sync (PolkitBackendInte ...@@ -883,7 +888,8 @@ polkit_backend_interactive_authority_check_authorization_sync (PolkitBackendInte
subject_is_active, subject_is_active,
action_id, action_id,
details, details,
implicit); implicit,
out_details);
} }
return ret; return ret;
......
...@@ -83,7 +83,8 @@ struct _PolkitBackendInteractiveAuthorityClass ...@@ -83,7 +83,8 @@ struct _PolkitBackendInteractiveAuthorityClass
gboolean subject_is_active, gboolean subject_is_active,
const gchar *action_id, const gchar *action_id,
PolkitDetails *details, PolkitDetails *details,
PolkitImplicitAuthorization implicit); PolkitImplicitAuthorization implicit,
PolkitDetails *out_details);
/*< private >*/ /*< private >*/
/* Padding for future expansion */ /* Padding for future expansion */
...@@ -138,7 +139,8 @@ PolkitImplicitAuthorization polkit_backend_interactive_authority_check_authoriza ...@@ -138,7 +139,8 @@ PolkitImplicitAuthorization polkit_backend_interactive_authority_check_authoriza
gboolean subject_is_active, gboolean subject_is_active,
const gchar *action_id, const gchar *action_id,
PolkitDetails *details, PolkitDetails *details,
PolkitImplicitAuthorization implicit); PolkitImplicitAuthorization implicit,
PolkitDetails *out_details);
G_END_DECLS G_END_DECLS
......
...@@ -79,7 +79,8 @@ static PolkitImplicitAuthorization polkit_backend_local_authority_check_authoriz ...@@ -79,7 +79,8 @@ static PolkitImplicitAuthorization polkit_backend_local_authority_check_authoriz
gboolean subject_is_active, gboolean subject_is_active,
const gchar *action_id, const gchar *action_id,
PolkitDetails *details, PolkitDetails *details,
PolkitImplicitAuthorization implicit); PolkitImplicitAuthorization implicit,
PolkitDetails *out_details);
G_DEFINE_TYPE_WITH_CODE (PolkitBackendLocalAuthority, G_DEFINE_TYPE_WITH_CODE (PolkitBackendLocalAuthority,
...@@ -257,7 +258,8 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv ...@@ -257,7 +258,8 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv
gboolean subject_is_active, gboolean subject_is_active,
const gchar *action_id, const gchar *action_id,
PolkitDetails *details, PolkitDetails *details,
PolkitImplicitAuthorization implicit) PolkitImplicitAuthorization implicit,
PolkitDetails *out_details)
{ {
PolkitBackendLocalAuthority *local_authority; PolkitBackendLocalAuthority *local_authority;
PolkitBackendLocalAuthorityPrivate *priv; PolkitBackendLocalAuthorityPrivate *priv;
...@@ -296,7 +298,8 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv ...@@ -296,7 +298,8 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv
details, details,
&ret_any, &ret_any,
&ret_inactive, &ret_inactive,
&ret_active)) &ret_active,
out_details))
{ {
if (subject_is_local && subject_is_active) if (subject_is_local && subject_is_active)
{ {
...@@ -330,7 +333,8 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv ...@@ -330,7 +333,8 @@ polkit_backend_local_authority_check_authorization_sync (PolkitBackendInteractiv
details, details,
&ret_any, &ret_any,
&ret_inactive, &ret_inactive,
&ret_active)) &ret_active,
out_details))
{ {
if (subject_is_local && subject_is_active) if (subject_is_local && subject_is_active)
{ {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "config.h" #include "config.h"
#include <string.h>
#include <polkit/polkit.h> #include <polkit/polkit.h>
#include "polkitbackendlocalauthorizationstore.h" #include "polkitbackendlocalauthorizationstore.h"
...@@ -79,6 +80,8 @@ typedef struct ...@@ -79,6 +80,8 @@ typedef struct
PolkitImplicitAuthorization result_any; PolkitImplicitAuthorization result_any;
PolkitImplicitAuthorization result_inactive; PolkitImplicitAuthorization result_inactive;
PolkitImplicitAuthorization result_active; PolkitImplicitAuthorization result_active;
GHashTable *return_value;
} LocalAuthorization; } LocalAuthorization;
static void static void
...@@ -89,6 +92,8 @@ local_authorization_free (LocalAuthorization *authorization) ...@@ -89,6 +92,8 @@ local_authorization_free (LocalAuthorization *authorization)
g_list_free (authorization->identity_specs); g_list_free (authorization->identity_specs);
g_list_foreach (authorization->action_specs, (GFunc) g_pattern_spec_free, NULL); g_list_foreach (authorization->action_specs, (GFunc) g_pattern_spec_free, NULL);
g_list_free (authorization->action_specs); g_list_free (authorization->action_specs);
if (authorization->return_value != NULL)
g_hash_table_unref (authorization->return_value);
g_free (authorization); g_free (authorization);
} }
...@@ -105,6 +110,7 @@ local_authorization_new (GKeyFile *key_file, ...@@ -105,6 +110,7 @@ local_authorization_new (GKeyFile *key_file,
gchar *result_any_string; gchar *result_any_string;
gchar *result_inactive_string; gchar *result_inactive_string;
gchar *result_active_string; gchar *result_active_string;
gchar **return_value_strings;
guint n; guint n;
identity_strings = NULL; identity_strings = NULL;
...@@ -112,6 +118,7 @@ local_authorization_new (GKeyFile *key_file, ...@@ -112,6 +118,7 @@ local_authorization_new (GKeyFile *key_file,
result_any_string = NULL; result_any_string = NULL;
result_inactive_string = NULL; result_inactive_string = NULL;
result_active_string = NULL; result_active_string = NULL;
return_value_strings = NULL;
authorization = g_new0 (LocalAuthorization, 1); authorization = g_new0 (LocalAuthorization, 1);
...@@ -221,6 +228,42 @@ local_authorization_new (GKeyFile *key_file, ...@@ -221,6 +228,42 @@ local_authorization_new (GKeyFile *key_file,
goto out; goto out;
} }
return_value_strings = g_key_file_get_string_list (key_file,
group,
"ReturnValue",
NULL,
error);
if (return_value_strings != NULL)
{
for (n = 0; return_value_strings[n] != NULL; n++)
{
gchar *p;
const gchar *key;
const gchar *value;
p = strchr (return_value_strings[n], '=');
if (p == NULL)
{
g_warning ("Item `%s' in ReturnValue is malformed. Ignoring.",
return_value_strings[n]);
continue;
}
*p = '\0';
key = return_value_strings[n];
value = p + 1;
if (authorization->return_value == NULL)
{
authorization->return_value = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
}
g_hash_table_insert (authorization->return_value, g_strdup (key), g_strdup (value));
}
}
authorization->id = g_strdup_printf ("%s::%s", filename, group); authorization->id = g_strdup_printf ("%s::%s", filename, group);
out: out:
...@@ -229,6 +272,7 @@ local_authorization_new (GKeyFile *key_file, ...@@ -229,6 +272,7 @@ local_authorization_new (GKeyFile *key_file,
g_free (result_any_string); g_free (result_any_string);
g_free (result_inactive_string); g_free (result_inactive_string);
g_free (result_active_string); g_free (result_active_string);
g_strfreev (return_value_strings);
return authorization; return authorization;
} }
...@@ -605,6 +649,7 @@ polkit_backend_local_authorization_store_ensure (PolkitBackendLocalAuthorization ...@@ -605,6 +649,7 @@ polkit_backend_local_authorization_store_ensure (PolkitBackendLocalAuthorization
* @out_result_any: Return location for the result for any subjects if the look up matched. * @out_result_any: Return location for the result for any subjects if the look up matched.
* @out_result_inactive: Return location for the result for subjects in local inactive sessions if the look up matched. * @out_result_inactive: Return location for the result for subjects in local inactive sessions if the look up matched.
* @out_result_active: Return location for the result for subjects in local active sessions if the look up matched. * @out_result_active: Return location for the result for subjects in local active sessions if the look up matched.
* @out_details: %NULL or a #PolkitDetails object to append key/value pairs to on a positive match.
* *
* Checks if an authorization entry from @store matches @identity, @action_id and @details. * Checks if an authorization entry from @store matches @identity, @action_id and @details.
* *
...@@ -618,7 +663,8 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization ...@@ -618,7 +663,8 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization
PolkitDetails *details, PolkitDetails *details,
PolkitImplicitAuthorization *out_result_any, PolkitImplicitAuthorization *out_result_any,
PolkitImplicitAuthorization *out_result_inactive, PolkitImplicitAuthorization *out_result_inactive,
PolkitImplicitAuthorization *out_result_active) PolkitImplicitAuthorization *out_result_active,
PolkitDetails *out_details)
{ {
GList *l, *ll; GList *l, *ll;
gboolean ret; gboolean ret;
...@@ -667,6 +713,19 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization ...@@ -667,6 +713,19 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization