Commit 169c130d authored by David Zeuthen's avatar David Zeuthen
Browse files

rip out the notion of Resources

It makes things a _lot more_ complicated having to deal with resources
and there's a much nicer way to deal with it: Punt it to the apps:

It's much more natural for the application to have a notion about
about what resources are "trusted" (and e.g. requires lesser
privileges) and what resources aren't.

Consider dial-up networking; here the privileged application that
performs the dial-up operation consults a list (maintained by the
system administrator) of allowed numbers to dial. If the unprivileged
networking UI applet that requests a number to be dialed is on the
list it uses the PolicyKit action 'nm-dialup-trusted-location', if it
isn't then it uses the PolicyKit action 'nm-dialup-untrusted-location'.
parent b9cf5bca
......@@ -73,7 +73,6 @@
<xi:include href="xml/polkit-policy-file-entry.xml"/>
<xi:include href="xml/polkit-policy-default.xml"/>
<xi:include href="xml/polkit-policy-cache.xml"/>
<xi:include href="xml/polkit-resource.xml"/>
<xi:include href="xml/polkit-seat.xml"/>
<xi:include href="xml/polkit-session.xml"/>
<xi:include href="xml/polkit-caller.xml"/>
......
SUBDIRS = default allow-all deny-all run-program grant
#SUBDIRS = default allow-all deny-all run-program grant
SUBDIRS = default grant
polkitconfdir = $(sysconfdir)/PolicyKit
dist_polkitconf_DATA = PolicyKit.conf
......@@ -47,11 +47,10 @@ _module_shutdown (PolKitModuleInterface *module_interface)
}
static PolKitResult
_module_can_session_access_resource (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitSession *session)
_module_can_session_do_action (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitSession *session)
{
PolKitResult result;
PolKitPolicyCache *cache;
......@@ -60,19 +59,16 @@ _module_can_session_access_resource (PolKitModuleInterface *module_interface,
result = POLKIT_RESULT_NO;
cache = polkit_context_get_policy_cache (pk_context);
pfe = polkit_policy_cache_get_entry (cache, action);
return polkit_policy_default_can_session_access_resource (
polkit_policy_file_entry_get_default (pfe),
action,
resource,
session);
return polkit_policy_default_can_session_do_action (polkit_policy_file_entry_get_default (pfe),
action,
session);
}
static PolKitResult
_module_can_caller_access_resource (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller)
_module_can_caller_do_action (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitCaller *caller)
{
PolKitResult result;
PolKitPolicyCache *cache;
......@@ -81,11 +77,9 @@ _module_can_caller_access_resource (PolKitModuleInterface *module_interface,
result = POLKIT_RESULT_NO;
cache = polkit_context_get_policy_cache (pk_context);
pfe = polkit_policy_cache_get_entry (cache, action);
return polkit_policy_default_can_caller_access_resource (
polkit_policy_file_entry_get_default (pfe),
action,
resource,
caller);
return polkit_policy_default_can_caller_do_action (polkit_policy_file_entry_get_default (pfe),
action,
caller);
}
polkit_bool_t
......@@ -99,8 +93,8 @@ polkit_module_set_functions (PolKitModuleInterface *module_interface)
polkit_module_set_func_initialize (module_interface, _module_init);
polkit_module_set_func_shutdown (module_interface, _module_shutdown);
polkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
polkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
polkit_module_set_func_can_session_do_action (module_interface, _module_can_session_do_action);
polkit_module_set_func_can_caller_do_action (module_interface, _module_can_caller_do_action);
ret = TRUE;
out:
......
......@@ -17,7 +17,11 @@ polkitmodule_LTLIBRARIES = \
$(NULL)
polkit_module_grant_la_SOURCES = polkit-module-grant.c
polkit_module_grant_la_SOURCES = \
$(top_srcdir)/polkit-grant/polkit-grant-database.h $(top_srcdir)/polkit-grant/polkit-grant-database.c \
polkit-module-grant.c
polkit_module_grant_la_LDFLAGS = -no-undefined -module -avoid-version
polkit_module_grant_la_LIBADD = $(top_builddir)/polkit/libpolkit.la @GLIB_LIBS@
......
......@@ -51,21 +51,19 @@ _module_shutdown (PolKitModuleInterface *module_interface)
static PolKitResult
_module_can_session_access_resource (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitSession *session)
_module_can_session_do_action (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitSession *session)
{
return POLKIT_RESULT_UNKNOWN_ACTION;
}
static PolKitResult
_module_can_caller_access_resource (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller)
_module_can_caller_do_action (PolKitModuleInterface *module_interface,
PolKitContext *pk_context,
PolKitAction *action,
PolKitCaller *caller)
{
char *grant_file;
PolKitSession *session;
......@@ -73,6 +71,7 @@ _module_can_caller_access_resource (PolKitModuleInterface *module_interface,
result = POLKIT_RESULT_UNKNOWN_ACTION;
#if 0
/* file format:
*
* file: /var/[lib,run]/PolicyKit/grant/<action-name>.grant
......@@ -106,22 +105,30 @@ _module_can_caller_access_resource (PolKitModuleInterface *module_interface,
if (!polkit_caller_get_uid (caller, &invoking_user_id))
goto out;
if (resource == NULL)
goto out;
if (!polkit_resource_get_resource_type (resource, &resource_type))
goto out;
if (!polkit_resource_get_resource_id (resource, &resource_id))
goto out;
if (resource == NULL) {
resource_type = "";
resource_id = "";
} else {
if (!polkit_resource_get_resource_type (resource, &resource_type))
goto out;
if (!polkit_resource_get_resource_id (resource, &resource_id))
goto out;
}
session_name = NULL;
if (!polkit_caller_get_ck_session (caller, &session))
goto out;
if (!polkit_caller_get_dbus_name (caller, &dbus_name))
goto out;
if (!polkit_session_get_ck_objref (session, &session_objpath))
goto out;
if (session == NULL) {
session_objpath = NULL;
session_name = NULL;
} else {
if (!polkit_session_get_ck_objref (session, &session_objpath))
goto out;
session_name = g_basename (session_objpath);
}
session_name = g_basename (session_objpath);
resource_str_to_hash = g_strdup_printf ("%s:%s", resource_type, resource_id);
resource_hash = g_str_hash (resource_str_to_hash);
g_free (resource_str_to_hash);
......@@ -142,8 +149,14 @@ _module_can_caller_access_resource (PolKitModuleInterface *module_interface,
* dbus_<dbusname>_<uid>_<action>_<resource-hash>.grant
*/
if (dbus_name == NULL)
dbus_name = "";
grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/dbus_%s_%d_%s_%u.grant",
dbus_name, invoking_user_id, action_name, resource_hash);
fprintf (stdout, "testing for file '%s'\n", grant_file);
if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) {
result = POLKIT_RESULT_YES;
g_free (grant_file);
......@@ -151,14 +164,16 @@ _module_can_caller_access_resource (PolKitModuleInterface *module_interface,
}
g_free (grant_file);
grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/session_%s_%d_%s_%u.grant",
session_name, invoking_user_id, action_name, resource_hash);
if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) {
result = POLKIT_RESULT_YES;
if (session_name != NULL) {
grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/session_%s_%d_%s_%u.grant",
session_name, invoking_user_id, action_name, resource_hash);
if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) {
result = POLKIT_RESULT_YES;
g_free (grant_file);
goto out;
}
g_free (grant_file);
goto out;
}
g_free (grant_file);
grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit/uid_%d_%s_%u.grant",
invoking_user_id, action_name, resource_hash);
......@@ -168,7 +183,7 @@ _module_can_caller_access_resource (PolKitModuleInterface *module_interface,
goto out;
}
g_free (grant_file);
#endif
out:
return result;
......@@ -185,8 +200,8 @@ polkit_module_set_functions (PolKitModuleInterface *module_interface)
polkit_module_set_func_initialize (module_interface, _module_init);
polkit_module_set_func_shutdown (module_interface, _module_shutdown);
polkit_module_set_func_can_session_access_resource (module_interface, _module_can_session_access_resource);
polkit_module_set_func_can_caller_access_resource (module_interface, _module_can_caller_access_resource);
polkit_module_set_func_can_session_do_action (module_interface, _module_can_session_do_action);
polkit_module_set_func_can_caller_do_action (module_interface, _module_can_caller_do_action);
ret = TRUE;
out:
......
......@@ -538,3 +538,134 @@ out:
g_free (ck_session_objpath);
return caller;
}
PolKitCaller *
polkit_caller_new_from_pid (DBusConnection *con, pid_t pid, DBusError *error)
{
PolKitCaller *caller;
uid_t uid;
char *selinux_context;
char *ck_session_objpath;
PolKitSession *session;
DBusMessage *message;
DBusMessage *reply;
DBusMessageIter iter;
char *str;
g_return_val_if_fail (con != NULL, NULL);
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail (! dbus_error_is_set (error), NULL);
selinux_context = NULL;
ck_session_objpath = NULL;
caller = NULL;
session = NULL;
/* TODO: Verify that PID exists */
/* TODO: FIXME */
uid = 500;
/* TODO: FIXME */
selinux_context = g_strdup ("user_u:system_r:hald_t");
message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
"/org/freedesktop/ConsoleKit/Manager",
"org.freedesktop.ConsoleKit.Manager",
"GetSessionForUnixProcess");
dbus_message_iter_init_append (message, &iter);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &pid);
reply = dbus_connection_send_with_reply_and_block (con, message, -1, error);
if (reply == NULL || dbus_error_is_set (error)) {
g_warning ("Error doing GetSessionForUnixProcess on ConsoleKit: %s: %s", error->name, error->message);
dbus_message_unref (message);
if (reply != NULL)
dbus_message_unref (reply);
/* OK, this is not a catastrophe; just means the caller is not a
* member of any session or that ConsoleKit is not available..
*/
goto not_in_session;
}
dbus_message_iter_init (reply, &iter);
dbus_message_iter_get_basic (&iter, &str);
ck_session_objpath = g_strdup (str);
dbus_message_unref (message);
dbus_message_unref (reply);
session = polkit_session_new_from_objpath (con, ck_session_objpath, uid, error);
if (session == NULL) {
g_warning ("Got a session objpath but couldn't construct session object!");
goto out;
}
if (!polkit_session_validate (session)) {
polkit_session_unref (session);
session = NULL;
goto out;
}
not_in_session:
caller = polkit_caller_new ();
if (caller == NULL) {
if (session != NULL) {
polkit_session_unref (session);
session = NULL;
}
goto out;
}
if (!polkit_caller_set_uid (caller, uid)) {
if (session != NULL) {
polkit_session_unref (session);
session = NULL;
}
polkit_caller_unref (caller);
caller = NULL;
goto out;
}
if (!polkit_caller_set_pid (caller, pid)) {
if (session != NULL) {
polkit_session_unref (session);
session = NULL;
}
polkit_caller_unref (caller);
caller = NULL;
goto out;
}
if (selinux_context != NULL) {
if (!polkit_caller_set_selinux_context (caller, selinux_context)) {
if (session != NULL) {
polkit_session_unref (session);
session = NULL;
}
polkit_caller_unref (caller);
caller = NULL;
goto out;
}
}
if (session != NULL) {
if (!polkit_caller_set_ck_session (caller, session)) {
if (session != NULL) {
polkit_session_unref (session);
session = NULL;
}
polkit_caller_unref (caller);
caller = NULL;
goto out;
}
polkit_session_unref (session); /* caller object now own this object */
session = NULL;
}
if (!polkit_caller_validate (caller)) {
polkit_caller_unref (caller);
caller = NULL;
goto out;
}
out:
g_free (selinux_context);
g_free (ck_session_objpath);
return caller;
}
......@@ -35,6 +35,8 @@ PolKitSession *polkit_session_new_from_cookie (DBusConnection *con, const cha
PolKitCaller *polkit_caller_new_from_dbus_name (DBusConnection *con, const char *dbus_name, DBusError *error);
PolKitCaller *polkit_caller_new_from_pid (DBusConnection *con, pid_t pid, DBusError *error);
#endif /* POLKIT_DBUS_H */
......
......@@ -20,6 +20,7 @@ libpolkit_grantinclude_HEADERS = \
polkit-grant.h
libpolkit_grant_la_SOURCES = \
polkit-grant-database.h polkit-grant-database.c \
polkit-grant.h polkit-grant.c
libpolkit_grant_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la
......
......@@ -41,6 +41,8 @@
#include <polkit-dbus/polkit-dbus.h>
#include "polkit-grant-database.h"
static int
conversation_function (int n,
const struct pam_message **msg,
......@@ -146,12 +148,16 @@ do_auth (const char *user_to_auth)
goto error;
}
#if 0
/* Hmm, this fails; TODO: investigate */
/* permitted access? */
rc = pam_acct_mgmt (pam_h, 0);
if (rc != PAM_SUCCESS) {
fprintf (stderr, "pam_acct_mgmt failed: %s\n", pam_strerror (pam_h, rc));
goto error;
}
#endif
/* did we auth the right user? */
rc = pam_get_item (pam_h, PAM_USER, &authed_user);
......@@ -174,9 +180,8 @@ error:
static polkit_bool_t
verify_with_polkit (const char *dbus_name,
pid_t caller_pid,
const char *action_name,
const char *resource_type,
const char *resource_name,
PolKitResult *result,
char **out_session_objpath)
{
......@@ -187,7 +192,6 @@ verify_with_polkit (const char *dbus_name,
DBusError error;
PolKitContext *pol_ctx;
PolKitAction *action;
PolKitResource *resource;
dbus_error_init (&error);
bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
......@@ -200,18 +204,18 @@ verify_with_polkit (const char *dbus_name,
action = polkit_action_new ();
polkit_action_set_action_id (action, action_name);
if (resource_type != NULL && resource_name != NULL) {
resource = polkit_resource_new ();
polkit_resource_set_resource_type (resource, resource_type);
polkit_resource_set_resource_id (resource, resource_name);
if (dbus_name != NULL && strlen (dbus_name) > 0) {
caller = polkit_caller_new_from_dbus_name (bus, dbus_name, &error);
if (caller == NULL) {
fprintf (stderr, "cannot get caller from dbus name\n");
goto out;
}
} else {
resource = NULL;
}
caller = polkit_caller_new_from_dbus_name (bus, dbus_name, &error);
if (caller == NULL) {
fprintf (stderr, "cannot get caller from dbus name\n");
goto out;
caller = polkit_caller_new_from_pid (bus, caller_pid, &error);
if (caller == NULL) {
fprintf (stderr, "cannot get caller from pid\n");
goto out;
}
}
if (!polkit_caller_get_ck_session (caller, &session)) {
......@@ -234,7 +238,7 @@ verify_with_polkit (const char *dbus_name,
goto out;
}
*result = polkit_context_can_caller_access_resource (pol_ctx, action, resource, caller);
*result = polkit_context_can_caller_do_action (pol_ctx, action, caller);
if (*result != POLKIT_RESULT_ONLY_VIA_ROOT_AUTH &&
*result != POLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION &&
......@@ -242,7 +246,8 @@ verify_with_polkit (const char *dbus_name,
*result != POLKIT_RESULT_ONLY_VIA_SELF_AUTH &&
*result != POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION &&
*result != POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS) {
fprintf (stderr, "given auth type is bogus\n");
fprintf (stderr, "given auth type (%d -> %s) is bogus\n",
*result, polkit_result_to_string_representation (*result));
goto out;
}
......@@ -329,12 +334,11 @@ error:
return FALSE;
}
/* synopsis: /usr/libexec/polkit-grant-helper <auth-type> <dbus-name> <action-name> <resource-type> <resource-name>
/* synopsis: polkit-grant-helper <auth-type> <dbus-name> <pid> <action-name>
*
* <dbus-name> : unique name of caller on the system message bus to grant privilege to
* <dbus-name> : unique name of caller on the system message bus to grant privilege to (may be blank)
* <pid> : process id of caller to grant privilege to
* <action-name> : the PolicyKit action
* <resource-type> : resource-type
* <resource-name> : resource-name
*
* PAM interaction happens via stdin/stdout.
*
......@@ -349,11 +353,10 @@ main (int argc, char *argv[])
{
int ret;
uid_t invoking_user_id;
pid_t caller_pid;
const char *invoking_user_name;
const char *dbus_name;
const char *action_name;
const char *resource_type;
const char *resource_name;
PolKitResult result;
const char *user_to_auth;
char *session_objpath;
......@@ -363,7 +366,7 @@ main (int argc, char *argv[])
ret = 3;
if (argc != 5) {
if (argc != 4) {
fprintf (stderr, "wrong use\n");
goto out;
}
......@@ -408,14 +411,12 @@ main (int argc, char *argv[])
setenv ("PATH", "/bin:/usr/bin", 1);
dbus_name = argv[1];
action_name = argv[2];
resource_type = argv[3];
resource_name = argv[4];
caller_pid = atoi(argv[2]); /* TODO: use safer function? */
action_name = argv[3];
fprintf (stderr, "dbus_name = %s\n", dbus_name);
fprintf (stderr, "caller_pid = %d\n", caller_pid);
fprintf (stderr, "action_name = %s\n", action_name);
fprintf (stderr, "resource_type = %s\n", resource_type);
fprintf (stderr, "resource_name = %s\n", resource_name);
ret = 2;
......@@ -423,7 +424,7 @@ main (int argc, char *argv[])
*
* verify that the given thing to auth for really supports grant by auth in the requested way
*/
if (!verify_with_polkit (dbus_name, action_name, resource_type, resource_name, &result, &session_objpath))
if (!verify_with_polkit (dbus_name, caller_pid, action_name, &result, &session_objpath))
goto out;
/* tell user about the grant details; e.g. whether it's auth_self_keep_always or auth_self etc. */
......@@ -439,6 +440,8 @@ main (int argc, char *argv[])
user_to_auth = invoking_user_name;
}
ret = 1;
/* OK, start auth! */
if (!do_auth (user_to_auth))
goto out;
......@@ -452,9 +455,14 @@ main (int argc, char *argv[])
polkit_result_to_string_representation (result));
fflush (stdout);
if (!get_and_validate_override_details (&result))
if (!get_and_validate_override_details (&result)) {
/* if this fails it means bogus input from user */
ret = 2;
goto out;
}
fprintf (stderr, "OK; TODO: write to database\n");
#if 0
/* TODO: FIXME: XXX: this format of storing granted privileges needs be redone
*
* this concerns these two files
......@@ -507,8 +515,10 @@ main (int argc, char *argv[])
fprintf (stderr, "file is '%s'\n", grant_file);
FILE *f = fopen (grant_file, "w");
fclose (f);
#endif
ret = 0;
out:
fprintf (stderr, "exiting with code %d\n", ret);
return ret;
}
......@@ -370,14 +370,12 @@ polkit_grant_cancel_auth (PolKitGrant *polkit_grant)
* polkit_grant_initiate_auth:
* @polkit_grant: the object
* @action: Action requested by caller
* @resource: Resource in question
* @caller: Caller in question
*
* Initiate authentication to obtain the privilege for the given
* @caller to perform the specified @action on the given
* @resource. The caller of this method must have setup callback
* functions using the method polkit_grant_set_functions() prior to
* calling this method.
* @caller to perform the specified @action. The caller of this method
* must have setup callback functions using the method
* polkit_grant_set_functions() prior to calling this method.
*
* Implementation-wise, this class uses a secure (e.g. as in that it
* checks all information and fundamenally don't trust the caller;
......@@ -390,43 +388,40 @@ polkit_grant_cancel_auth (PolKitGrant *polkit_grant)
* Returns: #TRUE only if authentication have been initiated.
**/
polkit_bool_t
polkit_grant_initiate_auth (PolKitGrant *polkit_grant,
PolKitAction *action,
PolKitResource *resource,
PolKitCaller *caller)
polkit_grant_initiate_auth (PolKitGrant *polkit_grant,
PolKitAction *action,
PolKitCaller *caller)
{
pid_t pid;
char *dbus_name;
char *action_id;
char *resource_type;
char *resource_id;
GError *g_error;
const char *helper_argv[6];
char *helper_argv[5];
g_return_val_if_fail (polkit_grant != NULL, FALSE);
/* check that callback functions have been properly set up */
g_return_val_if_fail (polkit_grant->func_done != NULL, FALSE);
if (!polkit_caller_get_dbus_name (caller, &dbus_name))
goto error;
if (!polkit_action_get_action_id (action, &action_id))
if (!polkit_caller_get_pid (caller, &pid))