From: David Zeuthen Date: Tue, 19 Jun 2007 23:59:54 +0000 (-0400) Subject: move all grant writing/checking into a separate private library X-Git-Tag: POLICY_KIT_0_3~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2ec20531b4976576f650acee5ed8f5fa3a3a9541;p=platform%2Fupstream%2Fpolkit.git move all grant writing/checking into a separate private library --- diff --git a/modules/grant/Makefile.am b/modules/grant/Makefile.am index 2cea430..52ff52a 100644 --- a/modules/grant/Makefile.am +++ b/modules/grant/Makefile.am @@ -17,13 +17,9 @@ polkitmodule_LTLIBRARIES = \ $(NULL) -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_SOURCES = 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@ +polkit_module_grant_la_LIBADD = $(top_builddir)/polkit/libpolkit.la @GLIB_LIBS@ $(top_builddir)/polkit-grant/libpolkit-grant-private.la clean-local : rm -f *~ diff --git a/modules/grant/polkit-module-grant.c b/modules/grant/polkit-module-grant.c index d1c3691..c0ea67b 100644 --- a/modules/grant/polkit-module-grant.c +++ b/modules/grant/polkit-module-grant.c @@ -65,13 +65,15 @@ _module_can_caller_do_action (PolKitModuleInterface *module_interface, PolKitAction *action, PolKitCaller *caller) { + return _polkit_grantdb_check_can_caller_do_action (pk_context, action, caller); + +#if 0 char *grant_file; PolKitSession *session; PolKitResult result; result = POLKIT_RESULT_UNKNOWN_ACTION; -#if 0 /* file format: * * file: /var/[lib,run]/PolicyKit/grant/.grant @@ -184,9 +186,6 @@ _module_can_caller_do_action (PolKitModuleInterface *module_interface, } g_free (grant_file); #endif - -out: - return result; } polkit_bool_t diff --git a/polkit-grant/Makefile.am b/polkit-grant/Makefile.am index d8a39d7..4e1bc1c 100644 --- a/polkit-grant/Makefile.am +++ b/polkit-grant/Makefile.am @@ -12,6 +12,11 @@ INCLUDES = \ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \ @GLIB_CFLAGS@ @DBUS_CFLAGS@ +noinst_LTLIBRARIES=libpolkit-grant-private.la + +libpolkit_grant_private_la_SOURCES = \ + polkit-grant-database.h polkit-grant-database.c + lib_LTLIBRARIES=libpolkit-grant.la libpolkit_grantincludedir=$(includedir)/PolicyKit/polkit-grant @@ -20,7 +25,6 @@ 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 @@ -30,7 +34,7 @@ libpolkit_grant_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE libexec_PROGRAMS = polkit-grant-helper polkit_grant_helper_SOURCES = polkit-grant-helper.c -polkit_grant_helper_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @AUTH_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la +polkit_grant_helper_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @AUTH_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la $(top_builddir)/polkit-grant/libpolkit-grant-private.la polkit_grant_alwaysdir = $(localstatedir)/lib/PolicyKit dist_polkit_grant_always_DATA = diff --git a/polkit-grant/polkit-grant-database.c b/polkit-grant/polkit-grant-database.c new file mode 100644 index 0000000..c6f96de --- /dev/null +++ b/polkit-grant/polkit-grant-database.c @@ -0,0 +1,303 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/*************************************************************************** + * + * polkit-grant-database.c : simple interface for storing and checking grants + * + * (This is an internal and private interface to PolicyKit. Do not use.) + * + * Copyright (C) 2007 David Zeuthen, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +/* TODO FIXME: this is Linux specific */ +static unsigned long long +get_start_time_for_pid (pid_t pid) +{ + char *filename; + char *contents; + gsize length; + unsigned long long start_time; + GError *error = NULL; + char **tokens; + char *p; + char *endp; + + start_time = 0; + contents = NULL; + + filename = g_strdup_printf ("/proc/%d/stat", pid); + if (filename == NULL) { + fprintf (stderr, "Out of memory\n"); + goto out; + } + + if (!g_file_get_contents (filename, &contents, &length, &error)) { + fprintf (stderr, "Cannot get contents of '%s': %s\n", filename, error->message); + g_error_free (error); + goto out; + } + + /* start time is the 19th token after the '(process name)' entry */ + + p = strchr (contents, ')'); + if (p == NULL) { + goto out; + } + p += 2; /* skip ') ' */ + if (p - contents >= (int) length) { + goto out; + } + + tokens = g_strsplit (p, " ", 0); + if (g_strv_length (tokens) < 20) { + goto out; + } + + start_time = strtoll (tokens[19], &endp, 10); + if (endp == tokens[19]) { + goto out; + } + + g_strfreev (tokens); + +out: + g_free (filename); + g_free (contents); + return start_time; +} + +#if 0 +static polkit_bool_t +ensure_dir (const char *file) +{ + char *dirname; + polkit_bool_t ret; + + ret = FALSE; + + dirname = g_path_get_dirname (file); + if (dirname == NULL) + goto out; + + if (g_file_test (dirname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { + /* TODO: check permissions? */ + ret = TRUE; + goto out; + } + + if (mkdir (dirname, 0570) != 0) { + fprintf (stderr, "Cannot create directory '%s': %s\n", dirname, strerror (errno)); + goto out; + } + + ret = TRUE; + +out: + return ret; +} +#endif + +static polkit_bool_t +_polkit_grantdb_write (const char *grant_file) +{ + int fd; + polkit_bool_t ret; + + ret = FALSE; + +#if 0 + if (!ensure_dir (grant_file)) + goto out; +#endif + + fd = open (grant_file, O_CREAT | O_RDWR, 0460); + if (fd < 0) { + fprintf (stderr, "Cannot create file '%s': %s\n", grant_file, strerror (errno)); + goto out; + } + /* Yessir, the file is empty */ + close (fd); + + ret = TRUE; + +out: + return ret; +} + +polkit_bool_t +_polkit_grantdb_write_pid (const char *action_id, pid_t pid) +{ + char *grant_file; + polkit_bool_t ret = FALSE; + unsigned long long pid_start_time; + + pid_start_time = get_start_time_for_pid (pid); + if (pid_start_time == 0) + goto out; + + grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/uid%d-pid-%d@%Lu-%s.grant", + getuid(), pid, pid_start_time, action_id); + if (grant_file == NULL) { + fprintf (stderr, "Out of memory\n"); + goto out; + } + + ret = _polkit_grantdb_write (grant_file); +out: + return ret; +} + +polkit_bool_t +_polkit_grantdb_write_keep_session (const char *action_id, const char *session_id) +{ + char *grant_file; + polkit_bool_t ret = FALSE; + + grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/uid%d-session-%s-%s.grant", + getuid(), g_basename (session_id), action_id); + if (grant_file == NULL) { + fprintf (stderr, "Out of memory\n"); + goto out; + } + + ret = _polkit_grantdb_write (grant_file); +out: + return ret; +} + +polkit_bool_t +_polkit_grantdb_write_keep_always (const char *action_id, uid_t uid) +{ + char *grant_file; + polkit_bool_t ret = FALSE; + + grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit/uid%d/%s.grant", + getuid(), action_id); + if (grant_file == NULL) { + fprintf (stderr, "Out of memory\n"); + goto out; + } + + ret = _polkit_grantdb_write (grant_file); +out: + return ret; +} + +PolKitResult +_polkit_grantdb_check_can_caller_do_action (PolKitContext *pk_context, + PolKitAction *action, + PolKitCaller *caller) +{ + char *grant_file; + PolKitResult result; + char *action_id; + uid_t invoking_user_id; + pid_t invoking_process_id; + PolKitSession *session; + char *session_objpath; + unsigned long long pid_start_time; + + grant_file = NULL; + result = POLKIT_RESULT_UNKNOWN_ACTION; + + if (caller == NULL) + goto out; + + if (!polkit_action_get_action_id (action, &action_id)) + goto out; + + if (!polkit_caller_get_uid (caller, &invoking_user_id)) + goto out; + + if (!polkit_caller_get_pid (caller, &invoking_process_id)) + goto out; + + session_objpath = NULL; + if (polkit_caller_get_ck_session (caller, &session)) { + if (!polkit_session_get_ck_objref (session, &session_objpath)) + session_objpath = NULL; + } + + pid_start_time = get_start_time_for_pid (invoking_process_id); + if (pid_start_time == 0) + goto out; + + /* first check what _write_pid may have left */ + grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/uid%d-pid-%d@%Lu-%s.grant", + invoking_user_id, invoking_process_id, pid_start_time, action_id); + if (grant_file == NULL) { + fprintf (stderr, "Out of memory\n"); + g_free (grant_file); + goto out; + } + if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) { + result = POLKIT_RESULT_YES; + g_free (grant_file); + goto out; + } + g_free (grant_file); + + /* second, check what _keep_session may have left */ + if (session_objpath != NULL) { + grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/uid%d-session-%s-%s.grant", + invoking_user_id, g_basename (session_objpath), action_id); + if (grant_file == NULL) { + fprintf (stderr, "Out of memory\n"); + g_free (grant_file); + goto out; + } + if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) { + result = POLKIT_RESULT_YES; + g_free (grant_file); + goto out; + } + g_free (grant_file); + } + + /* finally, check what _keep_always may have left */ + if (session_objpath != NULL) { + grant_file = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit/uid%d/%s.grant", + invoking_user_id, action_id); + if (grant_file == NULL) { + fprintf (stderr, "Out of memory\n"); + g_free (grant_file); + goto out; + } + if (g_file_test (grant_file, G_FILE_TEST_EXISTS)) { + result = POLKIT_RESULT_YES; + g_free (grant_file); + goto out; + } + g_free (grant_file); + } + +out: + return result; +} diff --git a/polkit-grant/polkit-grant-database.h b/polkit-grant/polkit-grant-database.h new file mode 100644 index 0000000..dd53e8e --- /dev/null +++ b/polkit-grant/polkit-grant-database.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/*************************************************************************** + * + * polkit-grant-database.h : simple interface for storing and checking grants + * + * (This is an internal and private interface to PolicyKit. Do not use.) + * + * Copyright (C) 2007 David Zeuthen, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + **************************************************************************/ + +#ifndef POLKIT_GRANT_DATABASE_H +#define POLKIT_GRANT_DATABASE_H + +#include + +PolKitResult _polkit_grantdb_check_can_caller_do_action (PolKitContext *pk_context, + PolKitAction *action, + PolKitCaller *caller); + +polkit_bool_t _polkit_grantdb_write_keep_always (const char *action_id, uid_t uid); + +polkit_bool_t _polkit_grantdb_write_keep_session (const char *action_id, const char *session_id); + +polkit_bool_t _polkit_grantdb_write_pid (const char *action_id, pid_t pid); + +#endif /* POLKIT_GRANT_DATABASE_H */ diff --git a/polkit-grant/polkit-grant-helper.c b/polkit-grant/polkit-grant-helper.c index 7cbe07f..8d12f40 100644 --- a/polkit-grant/polkit-grant-helper.c +++ b/polkit-grant/polkit-grant-helper.c @@ -363,6 +363,7 @@ main (int argc, char *argv[]) gid_t egid; struct group *group; struct passwd *pw; + polkit_bool_t dbres; ret = 3; @@ -461,7 +462,35 @@ main (int argc, char *argv[]) goto out; } - fprintf (stderr, "OK; TODO: write to database\n"); + fprintf (stderr, "OK; TODO: write to database: action_id=%s session_id=%s pid=%d\n", + action_name, session_objpath, caller_pid); + + switch (result) { + case POLKIT_RESULT_ONLY_VIA_ROOT_AUTH: + case POLKIT_RESULT_ONLY_VIA_SELF_AUTH: + dbres = _polkit_grantdb_write_pid (action_name, caller_pid); + break; + + case POLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION: + case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION: + dbres = _polkit_grantdb_write_keep_session (action_name, session_objpath); + break; + + case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS: + case POLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS: + dbres = _polkit_grantdb_write_keep_always (action_name, invoking_user_id); + break; + + default: + /* should never happen */ + goto out; + } + + if (!dbres) { + fprintf (stderr, "polkit-grant-helper: failed to write to grantdb\n"); + goto out; + } + #if 0 /* TODO: FIXME: XXX: this format of storing granted privileges needs be redone *