PolicyKit/polkitd Makefile.am, NONE, 1.1 debug-polkitd.sh, NONE,
1.1 main.c, NONE, 1.1 policy.c, NONE, 1.1 policy.h, NONE,
1.1 polkit-manager.c, NONE, 1.1 polkit-manager.h, NONE,
1.1 polkit-marshal.list, NONE, 1.1 polkit-session.c, NONE,
1.1 polkit-session.h, NONE, 1.1 polkitd-test.c, NONE,
1.1 run-polkitd.sh, NONE, 1.1 valgrind-polkitd.sh, NONE, 1.1
David Zeuthen
david at kemper.freedesktop.org
Mon Mar 13 22:14:35 PST 2006
- Previous message: PolicyKit/libpolkit Makefile.am, 1.1.1.1, 1.2 libpolkit-test.c,
1.1.1.1, NONE libpolkit.c, 1.1.1.1, 1.2 libpolkit.h, 1.1.1.1, 1.2
- Next message: PolicyKit/privileges Makefile.am, NONE,
1.1 desktop-console.privilege, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvs/hal/PolicyKit/polkitd
In directory kemper:/tmp/cvs-serv13970/polkitd
Added Files:
Makefile.am debug-polkitd.sh main.c policy.c policy.h
polkit-manager.c polkit-manager.h polkit-marshal.list
polkit-session.c polkit-session.h polkitd-test.c
run-polkitd.sh valgrind-polkitd.sh
Log Message:
2006-03-14 David Zeuthen <davidz at redhat.com>
Add a bunch of code; basically a full rewrite moving all queries
to the daemon.
* COPYING:
* Makefile.am:
* configure.in:
* libpolkit/Makefile.am:
* libpolkit/libpolkit-test.c:
* libpolkit/libpolkit.c: (libpolkit_new_context),
(libpolkit_free_context),
(libpolkit_get_allowed_resources_for_privilege_for_uid),
(libpolkit_is_uid_allowed_for_privilege),
(libpolkit_get_privilege_list):
* libpolkit/libpolkit.h:
* policy-kit.in:
* polkit-interface-manager.xml:
* polkit-interface-session.xml:
* polkit.pc.in:
* polkitd/Makefile.am:
* polkitd/debug-polkitd.sh:
* polkitd/main.c: (usage), (delete_pid), (main):
* polkitd/policy.c: (policy_util_set_policy_directory),
(policy_element_new), (policy_element_free),
(policy_element_free_list), (policy_element_dump),
(txt_backend_read_policy), (policy_get_whitelist),
(policy_get_blacklist), (policy_get_policies), (afp_process_elem),
(policy_get_allowed_resources_for_policy_for_uid_gid),
(policy_is_uid_gid_allowed_for_policy), (policy_util_uid_to_name),
(policy_util_gid_to_name), (policy_util_name_to_uid),
(policy_util_name_to_gid),
(policy_get_allowed_resources_for_policy_for_uid),
(policy_is_uid_allowed_for_policy), (getgrouplist):
* polkitd/policy.h:
* polkitd/polkit-manager.c: (caller_info_delete),
(polkit_manager_init), (polkit_manager_finalize),
(polkit_manager_class_init), (polkit_manager_error_quark),
(polkit_manager_error_get_type), (bus_name_owner_changed),
(session_remover), (session_finalized), (polkit_manager_new),
(uid_from_username), (safe_strcmp),
(polkit_manager_get_caller_info),
(polkit_manager_initiate_privilege_grant),
(polkit_manager_is_user_privileged),
(polkit_manager_get_allowed_resources_for_privilege),
(polkit_manager_list_privileges),
(polkit_manager_add_temporary_privilege),
(polkit_manager_remove_temporary_privilege):
* polkitd/polkit-manager.h:
* polkitd/polkit-marshal.list:
* polkitd/polkit-session.c: (polkit_session_init),
(polkit_session_finalize), (polkit_session_class_init),
(polkit_session_error_quark), (polkit_session_error_get_type),
(polkit_session_check_caller), (polkit_session_is_authenticated),
(polkit_session_get_auth_denied_reason), (safe_memset),
(my_conversation), (write_back_to_parent), (do_pam_auth),
(data_from_pam), (polkit_session_get_auth_details),
(polkit_session_initiate_auth), (polkit_session_get_questions),
(polkit_session_provide_answers), (polkit_session_close),
(polkit_session_grant_privilege_temporarily), (polkit_session_new),
(polkit_session_initiator_disconnected):
* polkitd/polkit-session.h:
* polkitd/polkitd-test.c: (my_exit), (do_check),
(write_test_policy), (do_read_tests), (main):
* polkitd/run-polkitd.sh:
* polkitd/valgrind-polkitd.sh:
* privileges/Makefile.am:
* privileges/desktop-console.privilege:
* tools/Makefile.am:
* tools/Makefile.in:
* tools/polkit-grant-privilege.c: (have_questions_handler),
(auth_done_handler), (do_grant_privilege), (usage), (main):
* tools/polkit-is-privileged.c: (usage), (main):
* tools/polkit-list-privileges.c: (usage), (main):
--- NEW FILE: Makefile.am ---
INCLUDES = \
-DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
-DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
-DPACKAGE_BIN_DIR=\""$(bindir)"\" \
-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
-I$(top_srcdir) \
@GLIB_CFLAGS@ \
@DBUS_GLIB_CFLAGS@
# polkitd
#
sbin_PROGRAMS = polkitd
polkitd_SOURCES = \
polkit-marshal.c polkit-marshal.h \
polkit-session.c polkit-session.h \
polkit-manager.c polkit-manager.h \
polkit-interface-manager-glue.h \
polkit-interface-session-glue.h \
policy.c policy.h \
main.c
polkitd_CFLAGS = -fno-strict-aliasing
polkitd_LDADD = @GLIB_LIBS@ @DBUS_GLIB_LIBS@ @AUTH_LIBS@
#### Init scripts fun
SCRIPT_IN_FILES=PolicyKit.in
## Red Hat start
if OS_TYPE_RED_HAT
initddir=$(sysconfdir)/rc.d/init.d
initd_SCRIPTS= \
PolicyKit
endif
## Red Hat end
# D-BUS configuration file
#
dbusdir = $(sysconfdir)/dbus-1/system.d
dist_dbus_DATA = PolicyKit.conf
# D-BUS glue
#
polkit-interface-manager-glue.h: ../polkit-interface-manager.xml Makefile.am
dbus-binding-tool --prefix=polkit_manager --mode=glib-server --output=polkit-interface-manager-glue.h ../polkit-interface-manager.xml
polkit-interface-session-glue.h: ../polkit-interface-session.xml Makefile.am
dbus-binding-tool --prefix=polkit_session --mode=glib-server --output=polkit-interface-session-glue.h ../polkit-interface-session.xml
BUILT_SOURCES = polkit-interface-manager-glue.h polkit-interface-session-glue.h
# Marshallers
#
polkit-marshal.c: Makefile polkit-marshal.list
glib-genmarshal --prefix=polkit_marshal $(srcdir)/polkit-marshal.list --header --body > $@.tmp && mv $@.tmp $@
polkit-marshal.h: Makefile polkit-marshal.list
glib-genmarshal --prefix=polkit_marshal $(srcdir)/polkit-marshal.list --header > $@.tmp && mv $@.tmp $@
BUILT_SOURCES += polkit-marshal.c polkit-marshal.h
# Test harness
#
check_PROGRAMS = polkitd-test
polkitd_test_SOURCES = \
policy.c policy.h \
polkitd-test.c
polkitd_test_LDADD = @GLIB_LIBS@
TESTS = polkitd-test
EXTRA_DIST = polkit-marshal.list
# Clean
#
clean-local:
rm -f *~ $(BUILT_SOURCES) PolicyKit.conf
--- NEW FILE: debug-polkitd.sh ---
#!/bin/sh
echo ========================================
echo Just type \'run\' to start debugging polkitd
echo ========================================
gdb run --args ./polkitd --no-daemon --verbose
--- NEW FILE: main.c ---
/***************************************************************************
* CVSID: $Id: main.c,v 1.1 2006/03/14 06:14:33 david Exp $
*
* main.c : Main for polkitd
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dbus/dbus-glib.h>
#include "polkit-session.h"
#include "polkit-manager.h"
#include "polkit-interface-session-glue.h"
#include "polkit-interface-manager-glue.h"
/** Print out program usage.
*
*/
static void
usage (int argc, char *argv[])
{
fprintf (stderr, "\n" "usage : polkitd [--no-daemon] [--verbose]\n");
fprintf (stderr,
"\n"
" -n, --no-daemon Do not daemonize\n"
" -v, --verbose Print out debug\n"
" -h, --help Show this information and exit\n"
" -V, --version Output version information and exit"
"\n"
"The PolicyKit daemon maintains a list of privileges and\n"
"provides interfaces for changing it.\n"
"\n"
"For more information visit http://freedesktop.org/Software/hal\n"
"\n");
}
static void
delete_pid (void)
{
unlink (POLKITD_PID_FILE);
}
int
main (int argc, char *argv[])
{
DBusGConnection *bus;
DBusGProxy *bus_proxy;
GError *error = NULL;
PolicyKitManager *manager;
GMainLoop *mainloop;
guint request_name_result;
int ret;
gboolean no_daemon = FALSE;
gboolean is_verbose = FALSE;
static const struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"no-daemon", no_argument, NULL, 'n'},
{"verbose", no_argument, NULL, 'v'},
{"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0}
};
ret = 1;
g_type_init ();
while (TRUE) {
int c;
c = getopt_long (argc, argv, "nhVv", long_options, NULL);
if (c == -1)
break;
switch (c) {
case 'n':
no_daemon = TRUE;
break;
case 'v':
is_verbose = TRUE;
break;
case 'h':
usage (argc, argv);
ret = 0;
goto out;
case 'V':
printf (PACKAGE_NAME " version " PACKAGE_VERSION "\n");
ret = 0;
goto out;
default:
usage (argc, argv);
goto out;
}
}
if (!no_daemon) {
int child_pid;
int dev_null_fd;
int pf;
ssize_t written;
char pid[9];
if (chdir ("/") < 0) {
g_warning ("Could not chdir to /: %s", strerror (errno));
goto out;
}
child_pid = fork ();
switch (child_pid) {
case -1:
g_warning ("Cannot fork(): %s", strerror (errno));
goto out;
case 0:
/* child */
dev_null_fd = open ("/dev/null", O_RDWR);
/* ignore if we can't open /dev/null */
if (dev_null_fd >= 0) {
/* attach /dev/null to stdout, stdin, stderr */
dup2 (dev_null_fd, 0);
dup2 (dev_null_fd, 1);
dup2 (dev_null_fd, 2);
close (dev_null_fd);
}
umask (022);
break;
default:
/* parent exits */
exit (0);
break;
}
/* create session */
setsid ();
/* remove old pid file */
unlink (POLKITD_PID_FILE);
/* make a new pid file */
if ((pf = open (POLKITD_PID_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) > 0) {
snprintf (pid, sizeof(pid), "%lu\n", (long unsigned) getpid ());
written = write (pf, pid, strlen(pid));
close (pf);
g_atexit (delete_pid);
}
} else {
g_debug (("not becoming a daemon"));
}
g_type_init ();
dbus_g_object_type_install_info (POLKIT_TYPE_MANAGER, &dbus_glib_polkit_manager_object_info);
dbus_g_object_type_install_info (POLKIT_TYPE_SESSION, &dbus_glib_polkit_session_object_info);
dbus_g_error_domain_register (POLKIT_MANAGER_ERROR, NULL, POLKIT_MANAGER_TYPE_ERROR);
dbus_g_error_domain_register (POLKIT_SESSION_ERROR, NULL, POLKIT_SESSION_TYPE_ERROR);
mainloop = g_main_loop_new (NULL, FALSE);
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (bus == NULL) {
g_warning ("Couldn't connect to system bus: %s", error->message);
g_error_free (error);
goto out;
}
bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus");
if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error,
G_TYPE_STRING, "org.freedesktop.PolicyKit",
G_TYPE_UINT, 0,
G_TYPE_INVALID,
G_TYPE_UINT, &request_name_result,
G_TYPE_INVALID)) {
g_warning ("Failed to acquire org.freedesktop.PolicyKit: %s", error->message);
g_error_free (error);
goto out;
}
manager = polkit_manager_new (bus, bus_proxy);
g_debug ("service running");
g_main_loop_run (mainloop);
ret = 0;
out:
return ret;
}
--- NEW FILE: policy.c ---
/***************************************************************************
* CVSID: $Id: policy.c,v 1.1 2006/03/14 06:14:33 david Exp $
*
* policy.c : Wraps policy
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <errno.h>
#include <glib.h>
#include "policy.h"
#ifdef __SUNPRO_C
#define __FUNCTION__ __func__
#endif
static char *policy_directory = PACKAGE_SYSCONF_DIR "/PolicyKit/privilege.d";
void
policy_util_set_policy_directory (const char *directory)
{
policy_directory = g_strdup (directory);
}
typedef enum {
POLICY_ELEMENT_TYPE_UID,
POLICY_ELEMENT_TYPE_GID
} PolicyElementType;
struct PolicyElement_s
{
PolicyElementType type;
union {
uid_t uid;
gid_t gid;
} id;
gboolean include_all;
gboolean exclude_all;
char *resource;
};
typedef struct PolicyElement_s PolicyElement;
static PolicyElement *
policy_element_new (void)
{
PolicyElement *elem;
elem = g_new0 (PolicyElement, 1);
return elem;
}
static void
policy_element_free (PolicyElement *elem)
{
g_free (elem->resource);
g_free (elem);
}
static void
policy_element_free_list (GList *policy_element_list)
{
GList *l;
for (l = policy_element_list; l != NULL; l = g_list_next (l)) {
PolicyElement *elem = (PolicyElement *) l->data;
policy_element_free (elem);
}
g_list_free (policy_element_list);
}
#if 0
static void
policy_element_dump (PolicyElement *elem, FILE* fp)
{
char *t;
if (elem->type == POLICY_ELEMENT_TYPE_UID)
t = "uid";
else if (elem->type == POLICY_ELEMENT_TYPE_GID)
t = "gid";
else
t = "(Unknown)";
fprintf (fp, "type: %s\n", t);
if (elem->type == POLICY_ELEMENT_TYPE_UID) {
if (elem->include_all) {
fprintf (fp, "uid: all\n");
} else if (elem->exclude_all) {
fprintf (fp, "uid: none\n");
} else {
fprintf (fp, "uid: %d\n", (int) elem->id.uid);
}
} else if (elem->type == POLICY_ELEMENT_TYPE_GID) {
if (elem->include_all) {
fprintf (fp, "gid: all\n");
} else if (elem->exclude_all) {
fprintf (fp, "gid: none\n");
} else {
fprintf (fp, "gid: %d\n", (int) elem->id.gid);
}
}
fprintf (fp, "resource: %s\n", elem->resource != NULL ? elem->resource : "(None)");
}
#endif
static PolicyResult
txt_backend_read_policy (const char *policy,
const char *key,
GList **result)
{
int i;
GKeyFile *keyfile;
GError *error;
PolicyResult rc;
char *path;
char *value = NULL;
char **tokens = NULL;
char *ttype = NULL;
char *tvalue = NULL;
char *tresource = NULL;
PolicyElement *elem = NULL;
GList *res;
GList *l;
char *token;
error = NULL;
rc = POLICY_RESULT_ERROR;
res = NULL;
*result = NULL;
keyfile = g_key_file_new ();
path = g_strdup_printf ("%s/%s.privilege", policy_directory, policy);
/*g_message ("Loading %s", path);*/
if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, &error)) {
g_warning ("Couldn't open key-file '%s': %s", path, error->message);
g_error_free (error);
rc = POLICY_RESULT_NO_SUCH_POLICY;
goto out;
}
value = g_key_file_get_string (keyfile, "Policy", key, &error);
if (value == NULL) {
g_warning ("Cannot get key '%s' in group 'Policy' in file '%s': %s", key, path, error->message);
g_error_free (error);
rc = POLICY_RESULT_ERROR;
goto out;
}
/*g_message ("value = '%s'", value);*/
tokens = g_strsplit (value, " ", 0);
for (i = 0; tokens[i] != NULL; i++) {
char **components;
int num_components;
token = tokens[i];
/*g_message (" token = '%s'", token);*/
ttype = NULL;
tvalue = NULL;
tresource = NULL;
elem = policy_element_new ();
components = g_strsplit (token, ":", 3);
num_components = g_strv_length (components);
if (num_components == 2) {
ttype = g_strdup (components[0]);
tvalue = g_strdup (components[1]);
tresource = NULL;
} else if (num_components == 3) {
ttype = g_strdup (components[0]);
tvalue = g_strdup (components[1]);
tresource = g_strdup (components[2]);
} else {
g_strfreev (components);
goto malformed_token;
}
g_strfreev (components);
/*g_message (" type='%s' value='%s' resource='%s'", ttype, tvalue, tresource != NULL ? tresource : "None");*/
if (strcmp (ttype, "uid") == 0) {
elem->type = POLICY_ELEMENT_TYPE_UID;
if (strcmp (tvalue, "__all__") == 0) {
elem->include_all = TRUE;
} else if (strcmp (tvalue, "__none__") == 0) {
elem->exclude_all = TRUE;
} else {
uid_t uid;
char *endp;
uid = (uid_t) g_ascii_strtoull (tvalue, &endp, 0);
if (endp[0] != '\0') {
uid = policy_util_name_to_uid (tvalue, NULL);
if (uid == (uid_t) -1) {
g_warning ("User '%s' does not exist", tvalue);
goto malformed_token;
}
}
elem->id.uid = uid;
}
} else if (strcmp (ttype, "gid") == 0) {
elem->type = POLICY_ELEMENT_TYPE_GID;
if (strcmp (tvalue, "__all__") == 0) {
elem->include_all = TRUE;
} else if (strcmp (tvalue, "__none__") == 0) {
elem->exclude_all = TRUE;
} else {
gid_t gid;
char *endp;
gid = (gid_t) g_ascii_strtoull (tvalue, &endp, 0);
if (endp[0] != '\0') {
gid = policy_util_name_to_gid (tvalue);
if (gid == (gid_t) -1) {
g_warning ("Group '%s' does not exist", tvalue);
goto malformed_token;
}
}
elem->id.gid = gid;
}
} else {
g_warning ("Token '%s' in key '%s' in group 'Policy' in file '%s' malformed",
token, key, path);
goto malformed_token;
}
if (tresource != NULL) {
elem->resource = g_strdup (tresource);
}
g_free (ttype);
g_free (tvalue);
g_free (tresource);
res = g_list_append (res, elem);
/*policy_element_dump (elem, stderr);*/
}
*result = res;
rc = POLICY_RESULT_OK;
goto out;
malformed_token:
g_warning ("Token '%s' in key '%s' in group 'Policy' in file '%s' malformed", token, key, path);
for (l = res; l != NULL; l = g_list_next (l)) {
policy_element_free ((PolicyElement *) l->data);
}
g_list_free (res);
policy_element_free (elem);
g_free (ttype);
g_free (tvalue);
g_free (tresource);
out:
g_strfreev (tokens);
g_free (value);
g_key_file_free (keyfile);
g_free (path);
return rc;
}
static PolicyResult
policy_get_whitelist (const char *policy,
GList **result)
{
return txt_backend_read_policy (policy, "Allow", result);
}
static PolicyResult
policy_get_blacklist (const char *policy,
GList **result)
{
return txt_backend_read_policy (policy, "Deny", result);
}
/** Return all elements in the white-list for a policy
*
* @param result On success set to a list of dynamically allocated strings.
* Must be freed by the caller.
* @return Whether the operation succeeded
*/
PolicyResult
policy_get_policies (GList **result)
{
GDir *dir;
GError *error;
const char *f;
error = NULL;
*result = NULL;
if ((dir = g_dir_open (policy_directory, 0, &error)) == NULL) {
g_critical ("Unable to open %s: %s", policy_directory, error->message);
g_error_free (error);
goto error;
}
while ((f = g_dir_read_name (dir)) != NULL) {
if (g_str_has_suffix (f, ".privilege")) {
char *s;
int pos;
s = g_strdup (f);
pos = strlen (s) - 10; /* .privilege - 10 chars */
if (pos > 0)
s[pos] = '\0';
*result = g_list_append (*result, s);
}
}
g_dir_close (dir);
return POLICY_RESULT_OK;
error:
return POLICY_RESULT_ERROR;
}
static void
afp_process_elem(PolicyElement *elem, gboolean *flag, uid_t uid, guint num_gids, gid_t *gid_list)
{
/*policy_element_dump (elem, stderr);*/
switch (elem->type) {
case POLICY_ELEMENT_TYPE_UID:
if (elem->include_all) {
*flag = TRUE;
} else if (elem->exclude_all) {
*flag = FALSE;
}else {
if (elem->id.uid == uid)
*flag = TRUE;
}
break;
case POLICY_ELEMENT_TYPE_GID:
if (elem->include_all) {
*flag = TRUE;
} else if (elem->exclude_all) {
*flag = FALSE;
}else {
guint i;
for (i = 0; i < num_gids; i++) {
if (elem->id.gid == gid_list[i])
*flag = TRUE;
}
}
break;
}
}
PolicyResult
policy_get_allowed_resources_for_policy_for_uid_gid (uid_t uid,
guint num_gids,
gid_t *gid_list,
const char *policy,
GList **result)
{
GList *l;
GList *whitelist;
GList *blacklist;
gboolean is_in_whitelist;
gboolean is_in_blacklist;
PolicyResult res;
whitelist = NULL;
blacklist = NULL;
*result = NULL;
res = POLICY_RESULT_ERROR;
res = policy_get_whitelist (policy, &whitelist);
if (res != POLICY_RESULT_OK)
goto out;
res = policy_get_blacklist (policy, &blacklist);
if (res != POLICY_RESULT_OK)
goto out;
is_in_whitelist = FALSE;
is_in_blacklist = FALSE;
/* Algorithm: check each resource in whitelist;
* if allowed, check against blacklist..
* if not in blacklist, push to results
*/
for (l = whitelist; l != NULL; l = g_list_next (l)) {
PolicyElement *elem;
gboolean in_whitelist;
elem = (PolicyElement *) l->data;
if (elem->resource != NULL) {
/* check if we're allowed for this resource */
afp_process_elem (elem, &in_whitelist, uid, num_gids, gid_list);
if (in_whitelist) {
GList *j;
gboolean in_blacklist;
/* in whitelist.. yes.. now check if this resource is in the black list*/
in_blacklist = FALSE;
for (j = blacklist; j != NULL; j = g_list_next (j)) {
PolicyElement *elem2;
elem2 = (PolicyElement *) j->data;
if (elem2->resource != NULL &&
strcmp (elem->resource, elem2->resource) == 0) {
afp_process_elem (elem2, &in_blacklist, uid, num_gids, gid_list);
if (in_blacklist)
break;
}
}
if (in_whitelist && !in_blacklist)
*result = g_list_append (*result, g_strdup (elem->resource));
}
}
}
res = POLICY_RESULT_OK;
out:
if (whitelist != NULL)
policy_element_free_list (whitelist);
if (blacklist != NULL)
policy_element_free_list (blacklist);
return res;
}
PolicyResult
policy_is_uid_gid_allowed_for_policy (uid_t uid,
guint num_gids,
gid_t *gid_list,
const char *policy,
const char *resource,
gboolean *result)
{
gboolean is_in_whitelist;
gboolean is_in_blacklist;
GList *l;
GList *whitelist;
GList *blacklist;
PolicyResult res;
whitelist = NULL;
blacklist = NULL;
res = POLICY_RESULT_ERROR;
res = policy_get_whitelist (policy, &whitelist);
if (res != POLICY_RESULT_OK)
goto out;
res = policy_get_blacklist (policy, &blacklist);
if (res != POLICY_RESULT_OK)
goto out;
is_in_whitelist = FALSE;
is_in_blacklist = FALSE;
/* Algorithm: To succeed.. we must be in the whitelist.. and not in the blacklist */
for (l = whitelist; l != NULL; l = g_list_next (l)) {
PolicyElement *elem;
elem = (PolicyElement *) l->data;
if ((elem->resource == NULL) ||
((resource != NULL) && (strcmp (elem->resource, resource) == 0))) {
afp_process_elem (elem, &is_in_whitelist, uid, num_gids, gid_list);
}
}
for (l = blacklist; l != NULL; l = g_list_next (l)) {
PolicyElement *elem;
elem = (PolicyElement *) l->data;
if ((elem->resource == NULL) ||
((resource != NULL) && (strcmp (elem->resource, resource) == 0))) {
afp_process_elem (elem, &is_in_blacklist, uid, num_gids, gid_list);
}
}
*result = is_in_whitelist && (!is_in_blacklist);
res = POLICY_RESULT_OK;
out:
if (whitelist != NULL)
policy_element_free_list (whitelist);
if (blacklist != NULL)
policy_element_free_list (blacklist);
return res;
}
char *
policy_util_uid_to_name (uid_t uid,
gid_t *default_gid)
{
int rc;
char *res;
char *buf = NULL;
unsigned int bufsize;
struct passwd pwd;
struct passwd *pwdp;
res = NULL;
bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
buf = g_new0 (char, bufsize);
rc = getpwuid_r (uid, &pwd, buf, bufsize, &pwdp);
if (rc != 0 || pwdp == NULL) {
/*g_warning ("getpwuid_r() returned %d", rc);*/
goto out;
}
res = g_strdup (pwdp->pw_name);
if (default_gid != NULL)
*default_gid = pwdp->pw_gid;
out:
g_free (buf);
return res;
}
char *
policy_util_gid_to_name (gid_t gid)
{
int rc;
char *res;
char *buf = NULL;
unsigned int bufsize;
struct group gbuf;
struct group *gbufp;
res = NULL;
bufsize = sysconf (_SC_GETGR_R_SIZE_MAX);
buf = g_new0 (char, bufsize);
rc = getgrgid_r (gid, &gbuf, buf, bufsize, &gbufp);
if (rc != 0 || gbufp == NULL) {
/*g_warning ("getgrgid_r() returned %d", rc);*/
goto out;
}
res = g_strdup (gbufp->gr_name);
out:
g_free (buf);
return res;
}
uid_t
policy_util_name_to_uid (const char *username, gid_t *default_gid)
{
int rc;
uid_t res;
char *buf = NULL;
unsigned int bufsize;
struct passwd pwd;
struct passwd *pwdp;
res = (uid_t) -1;
bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
buf = g_new0 (char, bufsize);
rc = getpwnam_r (username, &pwd, buf, bufsize, &pwdp);
if (rc != 0 || pwdp == NULL) {
/*g_warning ("getpwnam_r() returned %d", rc);*/
goto out;
}
res = pwdp->pw_uid;
if (default_gid != NULL)
*default_gid = pwdp->pw_gid;
out:
g_free (buf);
return res;
}
gid_t
policy_util_name_to_gid (const char *groupname)
{
int rc;
gid_t res;
char *buf = NULL;
unsigned int bufsize;
struct group gbuf;
struct group *gbufp;
res = (gid_t) -1;
bufsize = sysconf (_SC_GETGR_R_SIZE_MAX);
buf = g_new0 (char, bufsize);
rc = getgrnam_r (groupname, &gbuf, buf, bufsize, &gbufp);
if (rc != 0 || gbufp == NULL) {
/*g_warning ("getgrnam_r() returned %d", rc);*/
goto out;
}
res = gbufp->gr_gid;
out:
g_free (buf);
return res;
}
PolicyResult
policy_get_allowed_resources_for_policy_for_uid (uid_t uid,
const char *policy,
GList **result)
{
int num_groups = 0;
gid_t *groups = NULL;
char *username;
gid_t default_gid;
PolicyResult r;
r = POLICY_RESULT_ERROR;
if ((username = policy_util_uid_to_name (uid, &default_gid)) == NULL)
goto out;
if (getgrouplist(username, default_gid, NULL, &num_groups) < 0) {
groups = (gid_t *) g_new0 (gid_t, num_groups);
if (getgrouplist(username, default_gid, groups, &num_groups) < 0) {
g_warning ("getgrouplist() failed");
goto out;
}
}
r = policy_get_allowed_resources_for_policy_for_uid_gid (uid,
num_groups,
groups,
policy,
result);
out:
g_free (username);
g_free (groups);
return r;
}
PolicyResult
policy_is_uid_allowed_for_policy (uid_t uid,
const char *policy,
const char *resource,
gboolean *result)
{
int num_groups = 0;
gid_t *groups = NULL;
char *username;
gid_t default_gid;
PolicyResult r;
r = POLICY_RESULT_ERROR;
if ((username = policy_util_uid_to_name (uid, &default_gid)) == NULL)
goto out;
if (getgrouplist(username, default_gid, NULL, &num_groups) < 0) {
groups = (gid_t *) g_new0 (gid_t, num_groups);
if (getgrouplist(username, default_gid, groups, &num_groups) < 0) {
g_warning ("getgrouplist() failed");
goto out;
}
}
r = policy_is_uid_gid_allowed_for_policy (uid,
num_groups,
groups,
policy,
resource,
result);
out:
g_free (username);
g_free (groups);
return r;
}
#ifndef HAVE_GETGROUPLIST
/* Get group list for the named user.
* Return up to ngroups in the groups array.
* Return actual number of groups in ngroups.
* Return -1 if more groups found than requested.
*/
int
getgrouplist (const char *name, int baseid, int *groups, int *ngroups)
{
struct group *g;
int n = 0;
int i;
int ret;
if (*ngroups <= 0) {
return (-1);
}
*groups++ = baseid;
n++;
setgrent ();
while ((g = getgrent ()) != NULL) {
for (i = 0; g->gr_mem[i]; i++) {
if (strcmp (name, g->gr_mem[0]) == 0) {
*groups++ = g->gr_gid;
if (++n > *ngroups) {
break;
}
}
}
}
endgrent ();
ret = (n > *ngroups) ? -1 : n;
*ngroups = n;
return (ret);
}
#endif
--- NEW FILE: policy.h ---
/***************************************************************************
* CVSID: $Id: policy.h,v 1.1 2006/03/14 06:14:33 david Exp $
*
* policy.h : Wraps policy
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#ifndef POLICY_H
#define POLICY_H
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <glib.h>
typedef enum {
POLICY_RESULT_OK,
POLICY_RESULT_ERROR,
POLICY_RESULT_NO_SUCH_POLICY
} PolicyResult;
PolicyResult policy_get_policies (GList **result);
PolicyResult policy_is_uid_allowed_for_policy (uid_t uid,
const char *policy,
const char *resource,
gboolean *result);
PolicyResult policy_get_allowed_resources_for_policy_for_uid (uid_t uid,
const char *policy,
GList **result);
PolicyResult policy_get_allowed_resources_for_policy_for_uid_gid (uid_t uid,
guint num_gids,
gid_t *gid_list,
const char *policy,
GList **result);
PolicyResult policy_is_uid_gid_allowed_for_policy (uid_t uid,
guint num_gids,
gid_t *gid_list,
const char *policy,
const char *resource,
gboolean *result);
char *policy_util_uid_to_name (uid_t uid,
gid_t *default_gid);
char *policy_util_gid_to_name (gid_t gid);
uid_t policy_util_name_to_uid (const char *username,
gid_t *default_gid);
gid_t policy_util_name_to_gid (const char *groupname);
void policy_util_set_policy_directory (const char *directory);
#endif /* POLICY_H */
--- NEW FILE: polkit-manager.c ---
/***************************************************************************
* CVSID: $Id: polkit-manager.c,v 1.1 2006/03/14 06:14:33 david Exp $
*
* polkit-manager.c : Manager object
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#include <string.h>
#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "polkit-marshal.h"
#include "polkit-manager.h"
#include "polkit-session.h"
#include "policy.h"
typedef struct
{
uid_t user;
char *privilege;
char *resource;
pid_t pid_restriction;
} TemporaryPrivilege;
struct PolicyKitManagerPrivate
{
DBusGConnection *connection;
DBusGProxy *bus_proxy;
GList *temporary_privileges;
GHashTable *connection_name_to_caller_info;
GHashTable *connection_name_to_session_object;
};
G_DEFINE_TYPE(PolicyKitManager, polkit_manager, G_TYPE_OBJECT)
static GObjectClass *parent_class = NULL;
typedef struct {
uid_t uid;
pid_t pid;
} CallerInfo;
static void
caller_info_delete (gpointer data)
{
CallerInfo *caller_info = (CallerInfo *) data;
g_free (caller_info);
}
static void
polkit_manager_init (PolicyKitManager *manager)
{
manager->priv = g_new0 (PolicyKitManagerPrivate, 1);
manager->priv->connection = NULL;
manager->priv->temporary_privileges = NULL;
manager->priv->connection_name_to_caller_info = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
caller_info_delete);
manager->priv->connection_name_to_session_object = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
}
static void
polkit_manager_finalize (PolicyKitManager *manager)
{
dbus_g_connection_unref (manager->priv->connection);
g_hash_table_destroy (manager->priv->connection_name_to_caller_info);
g_free (manager->priv);
G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (manager));
}
static void
polkit_manager_class_init (PolicyKitManagerClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = (GObjectFinalizeFunc) polkit_manager_finalize;
parent_class = g_type_class_peek_parent (klass);
}
GQuark
polkit_manager_error_quark (void)
{
static GQuark ret = 0;
if (ret == 0)
ret = g_quark_from_static_string ("PolkitManagerObjectErrorQuark");
return ret;
}
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
GType
polkit_manager_error_get_type (void)
{
static GType etype = 0;
if (etype == 0) {
static const GEnumValue values[] = {
ENUM_ENTRY (POLKIT_MANAGER_ERROR_NO_SUCH_USER, "NoSuchUser"),
ENUM_ENTRY (POLKIT_MANAGER_ERROR_NO_SUCH_PRIVILEGE, "NoSuchPrivilege"),
ENUM_ENTRY (POLKIT_MANAGER_ERROR_NOT_PRIVILEGED, "NotPrivileged"),
ENUM_ENTRY (POLKIT_MANAGER_ERROR_ERROR, "Error"),
{ 0, 0, 0 }
};
g_assert (POLKIT_MANAGER_NUM_ERRORS == G_N_ELEMENTS (values) - 1);
etype = g_enum_register_static ("PolkitManagerError", values);
}
return etype;
}
static void
bus_name_owner_changed (DBusGProxy *bus_proxy,
const char *service_name,
const char *old_service_name,
const char *new_service_name,
gpointer user_data)
{
PolicyKitManager *manager = POLKIT_MANAGER (user_data);
/* track disconnects of clients */
if (strlen (new_service_name) == 0) {
CallerInfo *caller_info;
PolicyKitSession *session;
/* evict CallerInfo from cache */
caller_info = (CallerInfo *) g_hash_table_lookup (manager->priv->connection_name_to_caller_info,
old_service_name);
if (caller_info != NULL) {
g_hash_table_remove (manager->priv->connection_name_to_caller_info, old_service_name);
}
/* session object */
session = POLKIT_SESSION (g_hash_table_lookup (manager->priv->connection_name_to_session_object,
old_service_name));
if (session != NULL) {
/* possibly revoke temporary privileges granted */
polkit_session_initiator_disconnected (session);
/* end the session */
g_object_unref (session);
g_hash_table_remove (manager->priv->connection_name_to_session_object, old_service_name);
}
}
/*g_message ("NameOwnerChanged: service_name='%s', old_service_name='%s' new_service_name='%s'",
service_name, old_service_name, new_service_name);*/
}
static gboolean
session_remover (gpointer key,
gpointer value,
gpointer user_data)
{
if (value == user_data) {
return TRUE;
}
return FALSE;
}
static void
session_finalized (gpointer data,
GObject *where_the_object_was)
{
PolicyKitManager *manager = POLKIT_MANAGER (data);
g_hash_table_foreach_remove (manager->priv->connection_name_to_session_object,
session_remover,
where_the_object_was);
}
PolicyKitManager *
polkit_manager_new (DBusGConnection *connection, DBusGProxy *bus_proxy)
{
PolicyKitManager *manager;
manager = g_object_new (POLKIT_TYPE_MANAGER, NULL);
manager->priv->connection = dbus_g_connection_ref (connection);
dbus_g_connection_register_g_object (manager->priv->connection,
"/org/freedesktop/PolicyKit/Manager",
G_OBJECT (manager));
manager->priv->bus_proxy = bus_proxy;
dbus_g_object_register_marshaller (polkit_marshal_VOID__STRING_STRING_STRING,
G_TYPE_NONE,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_add_signal (bus_proxy, "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (bus_proxy, "NameOwnerChanged", G_CALLBACK (bus_name_owner_changed),
manager, NULL);
return manager;
}
static uid_t
uid_from_username (const char *user)
{
uid_t uid;
if (g_ascii_isdigit (user[0])) {
char *endp;
uid = (uid_t) g_ascii_strtoull (user, &endp, 0);
if (endp[0] != '\0') {
uid = (uid_t) -1;
}
} else {
uid = policy_util_name_to_uid (user, NULL);
}
return uid;
}
/* remote methods */
static int
safe_strcmp (const char *s1, const char *s2)
{
if (s1 == NULL || s2 == NULL)
return 0;
else
return strcmp (s1, s2);
}
gboolean
polkit_manager_get_caller_info (PolicyKitManager *manager,
const char *sender,
uid_t *calling_uid,
pid_t *calling_pid)
{
gboolean res;
CallerInfo *caller_info;
GError *error = NULL;
res = FALSE;
if (sender == NULL)
goto out;
caller_info = g_hash_table_lookup (manager->priv->connection_name_to_caller_info,
sender);
if (caller_info != NULL) {
res = TRUE;
*calling_uid = caller_info->uid;
*calling_pid = caller_info->pid;
/*g_message ("uid = %d (cached)", *calling_uid);
g_message ("pid = %d (cached)", *calling_pid);*/
goto out;
}
if (!dbus_g_proxy_call (manager->priv->bus_proxy, "GetConnectionUnixUser", &error,
G_TYPE_STRING, sender,
G_TYPE_INVALID,
G_TYPE_UINT, calling_uid,
G_TYPE_INVALID)) {
g_warning ("GetConnectionUnixUser() failed: %s", error->message);
g_error_free (error);
goto out;
}
if (!dbus_g_proxy_call (manager->priv->bus_proxy, "GetConnectionUnixProcessID", &error,
G_TYPE_STRING, sender,
G_TYPE_INVALID,
G_TYPE_UINT, calling_pid,
G_TYPE_INVALID)) {
g_warning ("GetConnectionUnixProcessID() failed: %s", error->message);
g_error_free (error);
goto out;
}
caller_info = g_new0 (CallerInfo, 1);
caller_info->uid = *calling_uid;
caller_info->pid = *calling_pid;
g_hash_table_insert (manager->priv->connection_name_to_caller_info,
g_strdup (sender),
caller_info);
res = TRUE;
/*g_message ("uid = %d", *calling_uid);
g_message ("pid = %d", *calling_pid);*/
out:
return res;
}
gboolean
polkit_manager_initiate_privilege_grant (PolicyKitManager *manager,
char *user,
char *privilege,
char *resource,
DBusGMethodInvocation *context)
{
uid_t calling_uid;
pid_t calling_pid;
uid_t uid;
PolicyKitSession *session;
char *sender;
/* TODO: need to handle limit number of session to prevent DOS.
* Or is dbus-daemon sufficient for that; I think so..
*/
if (!polkit_manager_get_caller_info (manager,
dbus_g_method_get_sender (context),
&calling_uid,
&calling_pid)) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_ERROR,
"An error occured."));
return FALSE;
}
sender = dbus_g_method_get_sender (context);
uid = uid_from_username (user);
if (uid == (uid_t) -1) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NO_SUCH_USER,
"There is no user '%s'.",
user));
return FALSE;
}
session = polkit_session_new (manager->priv->connection,
manager,
calling_uid,
calling_pid,
sender,
uid,
privilege,
strlen (resource) > 0 ? resource : NULL);
g_object_weak_ref (G_OBJECT (session),
session_finalized,
manager);
g_hash_table_insert (manager->priv->connection_name_to_session_object,
sender,
session);
//g_timeout_add (5 * 1000, destroy_session_after_timeout, session);
dbus_g_method_return (context,
g_strdup (((char *) g_object_get_data (G_OBJECT (session), "dbus_glib_object_path"))));
return TRUE;
}
gboolean
polkit_manager_is_user_privileged (PolicyKitManager *manager,
int pid,
char *user,
char *privilege,
char *resource,
DBusGMethodInvocation *context)
{
uid_t calling_uid;
pid_t calling_pid;
uid_t uid;
PolicyResult res;
gboolean is_privileged;
if (!polkit_manager_get_caller_info (manager,
dbus_g_method_get_sender (context),
&calling_uid,
&calling_pid)) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_ERROR,
"An error occured."));
return FALSE;
}
is_privileged = FALSE;
uid = uid_from_username (user);
if (uid == (uid_t) -1) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NO_SUCH_USER,
"There is no user '%s'.",
user));
return FALSE;
}
/* TODO: check if given uid is privileged to ask for this */
if (FALSE) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NOT_PRIVILEGED,
"You are not authorized to know this."));
return FALSE;
}
res = policy_is_uid_allowed_for_policy (uid,
privilege,
strlen (resource) > 0 ? resource : NULL,
&is_privileged);
switch (res) {
case POLICY_RESULT_OK:
break;
case POLICY_RESULT_NO_SUCH_POLICY:
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NO_SUCH_PRIVILEGE,
"There is no such privilege '%s'.",
privilege));
return FALSE;
default: /* explicit fallthrough */
case POLICY_RESULT_ERROR:
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_ERROR,
"An error occured."));
return FALSE;
}
/* check temporary lists */
if (!is_privileged) {
GList *i;
TemporaryPrivilege *p;
for (i = manager->priv->temporary_privileges; i != NULL; i = g_list_next (i)) {
p = (TemporaryPrivilege *) i->data;
gboolean res_match;
if (strlen (resource) == 0)
res_match = (p->resource == NULL);
else
res_match = (safe_strcmp (p->resource, resource) == 0);
if ((strcmp (p->privilege, privilege) == 0) &&
res_match &&
(p->user == uid) &&
((p->pid_restriction == -1) || (p->pid_restriction == pid))) {
is_privileged = TRUE;
break;
}
}
}
dbus_g_method_return (context, is_privileged);
return TRUE;
}
gboolean
polkit_manager_get_allowed_resources_for_privilege (PolicyKitManager *manager,
char *user,
char *privilege,
DBusGMethodInvocation *context)
{
uid_t calling_uid;
pid_t calling_pid;
int n;
GList *i;
GList *resources;
uid_t uid;
PolicyResult res;
TemporaryPrivilege *p;
char **resource_list;
if (!polkit_manager_get_caller_info (manager,
dbus_g_method_get_sender (context),
&calling_uid,
&calling_pid)) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_ERROR,
"An error occured."));
return FALSE;
}
uid = uid_from_username (user);
if (uid == (uid_t) -1) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NO_SUCH_USER,
"There is no user '%s'.",
user));
return FALSE;
}
/* TODO: check if given uid is privileged to ask for this */
if (FALSE) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NOT_PRIVILEGED,
"You are not authorized to know this."));
return FALSE;
}
res = policy_get_allowed_resources_for_policy_for_uid (uid,
privilege,
&resources);
switch (res) {
case POLICY_RESULT_OK:
break;
case POLICY_RESULT_NO_SUCH_POLICY:
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NO_SUCH_PRIVILEGE,
"There is no such privilege '%s'.",
privilege));
return FALSE;
default: /* explicit fallthrough */
case POLICY_RESULT_ERROR:
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_ERROR,
"An error occured."));
return FALSE;
}
/* check temporary list */
for (i = manager->priv->temporary_privileges; i != NULL; i = g_list_next (i)) {
p = (TemporaryPrivilege *) i->data;
if ((strcmp (p->privilege, privilege) == 0) &&
(p->resource != NULL) &&
(p->user == uid) &&
(p->pid_restriction == -1)) {
resources = g_list_append (resources, g_strdup (p->resource));
}
}
resource_list = g_new0 (char *, g_list_length (resources) + 1);
for (i = resources, n = 0; i != NULL; i = g_list_next (i)) {
char *resource = (char *) i->data;
resource_list[n++] = g_strdup (resource);
}
resource_list[n] = NULL;
g_list_foreach (resources, (GFunc) g_free, NULL);
g_list_free (resources);
dbus_g_method_return (context, resource_list);
return TRUE;
}
gboolean
polkit_manager_list_privileges (PolicyKitManager *manager,
DBusGMethodInvocation *context)
{
uid_t calling_uid;
pid_t calling_pid;
int n;
GList *i;
GList *privileges;
PolicyResult res;
char **privilege_list;
if (!polkit_manager_get_caller_info (manager,
dbus_g_method_get_sender (context),
&calling_uid,
&calling_pid)) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_ERROR,
"An error occured."));
return FALSE;
}
/* TODO: check if given uid is privileged to ask for this */
if (FALSE) {
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_NOT_PRIVILEGED,
"You are not authorized to know this."));
return FALSE;
}
res = policy_get_policies (&privileges);
switch (res) {
case POLICY_RESULT_OK:
break;
default: /* explicit fallthrough */
case POLICY_RESULT_ERROR:
dbus_g_method_return_error (context,
g_error_new (POLKIT_MANAGER_ERROR,
POLKIT_MANAGER_ERROR_ERROR,
"An error occured."));
return FALSE;
}
privilege_list = g_new0 (char *, g_list_length (privileges) + 1);
for (i = privileges, n = 0; i != NULL; i = g_list_next (i)) {
char *privilege = (char *) i->data;
privilege_list[n++] = g_strdup (privilege);
}
privilege_list[n] = NULL;
g_list_foreach (privileges, (GFunc) g_free, NULL);
g_list_free (privileges);
dbus_g_method_return (context, privilege_list);
return TRUE;
}
/* local methods */
gboolean
polkit_manager_add_temporary_privilege (PolicyKitManager *manager,
uid_t user,
const char *privilege,
const char *resource,
pid_t pid_restriction)
{
GList *i;
TemporaryPrivilege *p;
for (i = manager->priv->temporary_privileges; i != NULL; i = g_list_next (i)) {
p = (TemporaryPrivilege *) i->data;
if ((strcmp (p->privilege, privilege) == 0) &&
(safe_strcmp (p->resource, resource) == 0) &&
(p->user == user) &&
(p->pid_restriction == pid_restriction))
return FALSE;
}
p = g_new0 (TemporaryPrivilege, 1);
p->user = user;
p->privilege = g_strdup (privilege);
p->resource = g_strdup (resource);
p->pid_restriction = pid_restriction;
manager->priv->temporary_privileges = g_list_append (manager->priv->temporary_privileges, p);
return TRUE;
}
gboolean
polkit_manager_remove_temporary_privilege (PolicyKitManager *manager,
uid_t user,
const char *privilege,
const char *resource,
pid_t pid_restriction)
{
GList *i;
TemporaryPrivilege *p;
for (i = manager->priv->temporary_privileges; i != NULL; i = g_list_next (i)) {
p = (TemporaryPrivilege *) i->data;
if ((strcmp (p->privilege, privilege) == 0) &&
(safe_strcmp (p->resource, resource) == 0) &&
(p->user == user) &&
(p->pid_restriction == pid_restriction)) {
g_free (p->privilege);
g_free (p->resource);
manager->priv->temporary_privileges = g_list_remove (
manager->priv->temporary_privileges, p);
return TRUE;
}
}
return FALSE;
}
--- NEW FILE: polkit-manager.h ---
/***************************************************************************
* CVSID: $Id: polkit-manager.h,v 1.1 2006/03/14 06:14:33 david Exp $
*
* polkit-manager.h : Manager object
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#ifndef _POLKIT_MANAGER_H
#define _POLKIT_MANAGER_H
#include <unistd.h>
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
GQuark polkit_manager_error_quark (void);
#define POLKIT_MANAGER_ERROR (polkit_manager_error_quark ())
typedef enum
{
POLKIT_MANAGER_ERROR_NO_SUCH_USER = 0,
POLKIT_MANAGER_ERROR_NO_SUCH_PRIVILEGE = 1,
POLKIT_MANAGER_ERROR_NOT_PRIVILEGED = 2,
POLKIT_MANAGER_ERROR_ERROR = 3,
POLKIT_MANAGER_NUM_ERRORS
} PolkitManagerError;
GType polkit_manager_error_get_type (void);
#define POLKIT_MANAGER_TYPE_ERROR (polkit_manager_error_get_type ())
typedef struct PolicyKitManager PolicyKitManager;
typedef struct PolicyKitManagerClass PolicyKitManagerClass;
GType polkit_manager_get_type (void);
typedef struct PolicyKitManagerPrivate PolicyKitManagerPrivate;
struct PolicyKitManager
{
GObject parent;
PolicyKitManagerPrivate *priv;
};
struct PolicyKitManagerClass
{
GObjectClass parent;
};
#define POLKIT_TYPE_MANAGER (polkit_manager_get_type ())
#define POLKIT_MANAGER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), POLKIT_TYPE_MANAGER, PolicyKitManager))
#define POLKIT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), POLKIT_TYPE_MANAGER, PolicyKitManagerClass))
#define POLKIT_IS_MANAGER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), POLKIT_TYPE_MANAGER))
#define POLKIT_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POLKIT_TYPE_MANAGER))
#define POLKIT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), POLKIT_TYPE_MANAGER, PolicyKitManagerClass))
PolicyKitManager *polkit_manager_new (DBusGConnection *connection,
DBusGProxy *bus_proxy);
/* remote methods */
gboolean polkit_manager_initiate_privilege_grant (PolicyKitManager *manager,
char *user,
char *privilege,
char *resource,
DBusGMethodInvocation *context);
gboolean polkit_manager_is_user_privileged (PolicyKitManager *manager,
int pid,
char *user,
char *privilege,
char *resource,
DBusGMethodInvocation *context);
gboolean polkit_manager_get_allowed_resources_for_privilege (PolicyKitManager *manager,
char *user,
char *privilege,
DBusGMethodInvocation *context);
gboolean polkit_manager_list_privileges (PolicyKitManager *manager,
DBusGMethodInvocation *context);
/* local methods */
gboolean polkit_manager_get_caller_info (PolicyKitManager *manager,
const char *sender,
uid_t *calling_uid,
pid_t *calling_pid);
gboolean polkit_manager_add_temporary_privilege (PolicyKitManager *manager,
uid_t user,
const char *privilege,
const char *resource,
pid_t pid_restriction);
gboolean polkit_manager_remove_temporary_privilege (PolicyKitManager *manager,
uid_t user,
const char *privilege,
const char *resource,
pid_t pid_restriction);
#endif /* _POLKIT_MANAGER_H */
--- NEW FILE: polkit-marshal.list ---
VOID:STRING,STRING,STRING
--- NEW FILE: polkit-session.c ---
/***************************************************************************
* CVSID: $Id: polkit-session.c,v 1.1 2006/03/14 06:14:33 david Exp $
*
* polkit-session.c : Session object
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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
[...964 lines suppressed...]
void
polkit_session_initiator_disconnected (PolicyKitSession *session)
{
/*g_debug ("initiator disconnected");*/
if (session->priv->have_granted_temp_privileges) {
if (!polkit_manager_remove_temporary_privilege (session->priv->manager,
session->priv->grant_to_uid,
session->priv->grant_privilege,
session->priv->grant_resource,
session->priv->grant_pid_restriction)) {
g_warning ("Could not remove tmp priv '%s' to uid %d for resource '%s' on pid %d",
session->priv->grant_privilege,
session->priv->grant_to_uid,
session->priv->grant_resource,
session->priv->grant_pid_restriction);
}
}
}
--- NEW FILE: polkit-session.h ---
/***************************************************************************
* CVSID: $Id: polkit-session.h,v 1.1 2006/03/14 06:14:33 david Exp $
*
* polkit-session.h : Session object
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#ifndef _POLKIT_SESSION_H
#define _POLKIT_SESSION_H
#include <unistd.h>
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "polkit-manager.h"
GQuark polkit_session_error_quark (void);
#define POLKIT_SESSION_ERROR (polkit_session_error_quark ())
typedef enum
{
POLKIT_SESSION_ERROR_AUTHENTICATION_IN_PROGRESS = 0,
POLKIT_SESSION_ERROR_AUTHENTICATION_ALREADY_INITIATED = 1,
POLKIT_SESSION_ERROR_NO_QUESTIONS = 2,
POLKIT_SESSION_ERROR_AUTHENTICATION_WAS_NOT_DENIED = 3,
POLKIT_SESSION_ERROR_NO_RESOURCES = 4,
POLKIT_SESSION_ERROR_AUTHENTICATION_NOT_DONE = 5,
POLKIT_SESSION_ERROR_AUTHENTICATION_FAILED = 6,
POLKIT_SESSION_ERROR_NOT_INITIATOR = 7,
POLKIT_SESSION_NUM_ERRORS
} PolkitSessionError;
GType polkit_session_error_get_type (void);
#define POLKIT_SESSION_TYPE_ERROR (polkit_session_error_get_type ())
typedef struct PolicyKitSession PolicyKitSession;
typedef struct PolicyKitSessionClass PolicyKitSessionClass;
GType polkit_session_get_type (void);
typedef struct PolicyKitSessionPrivate PolicyKitSessionPrivate;
struct PolicyKitSession
{
GObject parent;
PolicyKitSessionPrivate *priv;
};
struct PolicyKitSessionClass
{
GObjectClass parent;
};
#define POLKIT_TYPE_SESSION (polkit_session_get_type ())
#define POLKIT_SESSION(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), POLKIT_TYPE_SESSION, PolicyKitSession))
#define POLKIT_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), POLKIT_TYPE_SESSION, PolicyKitSessionClass))
#define POLKIT_IS_SESSION(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), POLKIT_TYPE_SESSION))
#define POLKIT_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POLKIT_TYPE_SESSION))
#define POLKIT_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), POLKIT_TYPE_SESSION, PolicyKitSessionClass))
PolicyKitSession *polkit_session_new (DBusGConnection *connection,
PolicyKitManager *manager,
uid_t calling_uid,
pid_t calling_pid,
const char *calling_dbus_name,
uid_t uid,
const char *privilege,
const char *resource);
/* remote methods */
gboolean polkit_session_is_authenticated (PolicyKitSession *session,
DBusGMethodInvocation *context);
gboolean polkit_session_initiate_auth (PolicyKitSession *session,
DBusGMethodInvocation *context);
gboolean polkit_session_get_questions (PolicyKitSession *session,
DBusGMethodInvocation *context);
gboolean polkit_session_provide_answers (PolicyKitSession *session,
char **answers,
DBusGMethodInvocation *context);
gboolean polkit_session_close (PolicyKitSession *session,
gboolean do_not_revoke_privilege,
DBusGMethodInvocation *context);
gboolean polkit_session_get_auth_details (PolicyKitSession *session,
DBusGMethodInvocation *context);
gboolean polkit_session_get_auth_denied_reason (PolicyKitSession *session,
DBusGMethodInvocation *context);
gboolean polkit_session_grant_privilege_temporarily (PolicyKitSession *session,
gboolean restrict_to_callers_pid,
DBusGMethodInvocation *context);
/* local methods */
void polkit_session_initiator_disconnected (PolicyKitSession *session);
#endif /* _POLKIT_SESSION_H */
--- NEW FILE: polkitd-test.c ---
/***************************************************************************
* CVSID: $Id: polkitd-test.c,v 1.1 2006/03/14 06:14:33 david Exp $
*
* polkitd-test.c : Test harness for PolicyKit daemon
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <glib/gstdio.h>
#include "policy.h"
static char *testdir;
static void
my_exit (int exit_code)
{
int rc;
GDir *dir;
GError *err;
const char *f;
g_print ("Removing tmpdir '%s'\n", testdir);
err = NULL;
if ((dir = g_dir_open (testdir, 0, &err)) == NULL) {
g_warning ("Unable to open %s: %s", testdir, err->message);
g_error_free (err);
goto error;
}
while ((f = g_dir_read_name (dir)) != NULL) {
char *file;
file = g_strdup_printf ("%s/%s", testdir, f);
rc = g_unlink (file);
if (rc != 0) {
g_warning ("Unable to unlink %s: %d (%s)", file, errno, strerror (errno));
goto error;
}
g_free (file);
}
g_dir_close (dir);
rc = g_rmdir (testdir);
if (rc != 0) {
g_warning ("Unable to rmdir %s: %d (%s)", testdir, errno, strerror (errno));
goto error;
}
error:
exit (exit_code);
}
static void
do_check (const char *policy,
uid_t uid,
int num_gids,
gid_t *gids,
const char *resource,
gboolean expected)
{
int i;
gboolean allowed;
char *gidstring;
GString *str;
str = g_string_new ("");
for (i = 0; i < num_gids; i++) {
if (i != 0)
g_string_append (str, ", ");
g_string_append_printf (str, "%d", gids[i]);
}
gidstring = g_string_free (str, FALSE);
if (POLICY_RESULT_OK != policy_is_uid_gid_allowed_for_policy (
uid, num_gids, gids, policy, resource, &allowed)) {
g_warning ("fail: no policy %s", policy);
my_exit (1);
}
if (allowed != expected) {
g_warning ("fail: for uid %d (gids %s) expected %s on privilege '%s' for resource '%s' but got %s",
uid, gidstring,
expected ? "TRUE" : "FALSE",
policy,
(char*) (resource != NULL ? resource : ""),
allowed ? "TRUE" : "FALSE");
my_exit (1);
}
g_print ("pass: uid %d (gids %s) got %s on privilege '%s' for resource '%s'\n",
uid, gidstring,
expected ? "TRUE " : "FALSE",
policy,
(char*) (resource != NULL ? resource : ""));
g_free (gidstring);
}
static void
write_test_policy (const char *policy, const char *allow_rule, const char *deny_rule)
{
char *file;
FILE *f;
file = g_strdup_printf ("%s/%s.privilege", testdir, policy);
f = fopen (file, "w");
if (f == NULL) {
g_warning ("Cannot created test policy '%s'", file);
my_exit (1);
}
fprintf (f,
"[Policy]\n"
"Allow=%s\n"
"Deny=%s\n",
allow_rule, deny_rule);
fclose (f);
g_print ("Created test policy '%s' at '%s'\n"
" Allow '%s'\n"
" Deny '%s'\n",
policy, file, allow_rule, deny_rule);
g_free (file);
}
static void
do_read_tests (void)
{
gid_t gid500[1] = {500};
int gid500_len = sizeof (gid500) / sizeof (gid_t);
gid_t gid501[1] = {501};
int gid501_len = sizeof (gid501) / sizeof (gid_t);
gid_t gid502[1] = {502};
int gid502_len = sizeof (gid502) / sizeof (gid_t);
gid_t gid500_1[2] = {500, 1};
int gid500_1_len = sizeof (gid500_1) / sizeof (gid_t);
gid_t gid501_1[2] = {501, 1};
int gid501_1_len = sizeof (gid501_1) / sizeof (gid_t);
gid_t gid502_1[2] = {502, 1};
int gid502_1_len = sizeof (gid502_1) / sizeof (gid_t);
/* feel free to add more tests here */
write_test_policy ("test0", "uid:__none__ uid:500", "");
do_check ("test0", 500, gid500_len, gid500, NULL, TRUE);
do_check ("test0", 501, gid501_len, gid501, NULL, FALSE);
do_check ("test0", 502, gid502_len, gid502, NULL, FALSE);
write_test_policy ("test1", "uid:__all__", "uid:500:res0");
do_check ("test1", 500, gid500_len, gid500, NULL, TRUE);
do_check ("test1", 501, gid501_len, gid501, NULL, TRUE);
do_check ("test1", 502, gid502_len, gid502, NULL, TRUE);
do_check ("test1", 500, gid500_len, gid500, "res0", FALSE);
do_check ("test1", 501, gid501_len, gid501, "res0", TRUE);
do_check ("test1", 502, gid502_len, gid502, "res0", TRUE);
do_check ("test1", 500, gid500_len, gid500, "res1", TRUE);
do_check ("test1", 501, gid501_len, gid501, "res1", TRUE);
do_check ("test1", 502, gid502_len, gid502, "res1", TRUE);
write_test_policy ("test2", "gid:1", "uid:501");
do_check ("test2", 500, gid500_len, gid500, NULL, FALSE);
do_check ("test2", 501, gid501_len, gid501, NULL, FALSE);
do_check ("test2", 502, gid502_len, gid502, NULL, FALSE);
do_check ("test2", 500, gid500_1_len, gid500_1, NULL, TRUE);
do_check ("test2", 501, gid501_1_len, gid501_1, NULL, FALSE);
do_check ("test2", 502, gid502_1_len, gid502_1, NULL, TRUE);
write_test_policy ("test3", "gid:1 uid:502:res1", "uid:501 uid:500:res0");
do_check ("test3", 500, gid500_1_len, gid500_1, "res0", FALSE);
do_check ("test3", 501, gid501_1_len, gid501_1, "res0", FALSE);
do_check ("test3", 502, gid502_1_len, gid502_1, "res0", TRUE);
do_check ("test3", 500, gid500_1_len, gid500_1, "res1", TRUE);
do_check ("test3", 501, gid501_1_len, gid501_1, "res1", FALSE);
do_check ("test3", 502, gid502_1_len, gid502_1, "res1", TRUE);
do_check ("test3", 500, gid500_len, gid500, "res1", FALSE);
do_check ("test3", 501, gid501_len, gid501, "res1", FALSE);
do_check ("test3", 502, gid502_len, gid502, "res1", TRUE);
write_test_policy ("test4", "gid:1:res1 uid:500:res2", "gid:502:res2");
do_check ("test4", 500, gid500_1_len, gid500_1, "res0", FALSE);
do_check ("test4", 501, gid501_1_len, gid501_1, "res0", FALSE);
do_check ("test4", 502, gid502_1_len, gid502_1, "res0", FALSE);
do_check ("test4", 500, gid500_1_len, gid500_1, "res1", TRUE);
do_check ("test4", 501, gid501_1_len, gid501_1, "res1", TRUE);
do_check ("test4", 502, gid502_1_len, gid502_1, "res1", TRUE);
do_check ("test4", 500, gid500_len, gid500, "res2", TRUE);
do_check ("test4", 501, gid501_len, gid501, "res2", FALSE);
do_check ("test4", 502, gid502_len, gid502, "res2", FALSE);
write_test_policy ("test5", "gid:1", "uid:500:res-has-:colon-in-name");
do_check ("test5", 500, gid500_1_len, gid500_1, "res-has-:colon-in-name", FALSE);
do_check ("test5", 501, gid501_1_len, gid501_1, "res-has-:colon-in-name", TRUE);
do_check ("test5", 502, gid502_1_len, gid502_1, "res-has-:colon-in-name", TRUE);
do_check ("test5", 500, gid500_len, gid500, "res-has-:colon-in-name", FALSE);
do_check ("test5", 501, gid501_len, gid501, "res-has-:colon-in-name", FALSE);
do_check ("test5", 502, gid502_len, gid502, "res-has-:colon-in-name", FALSE);
}
int
main (int argc, char *argv[])
{
int i;
GList *l;
GList *policies;
testdir = g_strdup ("/tmp/policy-test-XXXXXX");
testdir = mkdtemp (testdir);
if (testdir == NULL) {
g_warning ("Cannot create tmpdir, errno %d (%s)", errno, strerror (errno));
g_free (testdir);
exit (1);
}
g_message ("policy-test started; using tmpdir=%s", testdir);
policy_util_set_policy_directory (testdir);
do_read_tests ();
if (policy_get_policies (&policies) != POLICY_RESULT_OK) {
g_message ("Cannot get policies");
goto fail;
}
g_print ("Loaded %d policies\n", g_list_length (policies));
for (l = policies, i = 0; l != NULL; l = g_list_next (l), i++) {
const char *policy;
policy = (const char *) l->data;
g_print (" policy %d: '%s'\n", i, policy);
}
g_list_foreach (policies, (GFunc) g_free, NULL);
g_list_free (policies);
g_print ("policy-test completed\n");
my_exit (0);
fail:
my_exit (1);
return 1;
}
--- NEW FILE: run-polkitd.sh ---
#!/bin/sh
./polkitd --no-daemon --verbose
--- NEW FILE: valgrind-polkitd.sh ---
#!/bin/sh
valgrind --num-callers=20 --show-reachable=yes --leak-check=yes --tool=memcheck ./polkitd --no-daemon --verbose
- Previous message: PolicyKit/libpolkit Makefile.am, 1.1.1.1, 1.2 libpolkit-test.c,
1.1.1.1, NONE libpolkit.c, 1.1.1.1, 1.2 libpolkit.h, 1.1.1.1, 1.2
- Next message: PolicyKit/privileges Makefile.am, NONE,
1.1 desktop-console.privilege, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the hal-commit
mailing list