From 95d37dca6ec5420c51e0b967d4c3f4e5389de724 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Fri, 8 Sep 2017 14:57:22 +0300 Subject: [PATCH 01/12] Removed some dead code. Clang static analysis no longer reports any issues. Signed-off-by: Ismo Puustinen --- groupcheck.c | 18 +----------------- groupcheck.h | 3 --- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/groupcheck.c b/groupcheck.c index e766bf3..682abca 100644 --- a/groupcheck.c +++ b/groupcheck.c @@ -165,10 +165,8 @@ bool check_allowed(sd_bus *bus, struct conf_data *conf_data, break; case SUBJECT_KIND_SYSTEM_BUS_NAME: - if (bus == NULL) { - r = -EINVAL; + if (bus == NULL) goto end; - } r = sd_bus_get_name_creds(bus, subject->data.b.system_bus_name, mask, &creds); if (r < 0) @@ -840,17 +838,3 @@ int load_directory(struct conf_data *conf_data, const char *dirname) closedir(dir); return r; } - -const char *find_policy_file() -{ - struct stat s; - const char *dynamic_conf = "/etc/groupcheck.policy"; - const char *default_conf = "/usr/share/defaults/etc/groupcheck.policy"; - - if (stat(dynamic_conf, &s) == 0) - return dynamic_conf; - else if (stat(default_conf, &s) == 0) - return default_conf; - - return NULL; -} diff --git a/groupcheck.h b/groupcheck.h index 9911815..4c9e01b 100644 --- a/groupcheck.h +++ b/groupcheck.h @@ -69,9 +69,6 @@ struct subject { * parameters, "data" is an input parameter. */ int initialize_bus(sd_bus **bus, sd_bus_slot **slot, struct conf_data *data); -/* Return the policy file path from the search paths. */ -const char *find_policy_file(); - /* Load a policy file. The resulting struct must be freed by the caller. */ int load_file(struct conf_data *conf_data, const char *filename); int load_directory(struct conf_data *conf_data, const char *filename); From 721e5bb3cc206378f484d58ef07f192bd698591e Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Mon, 11 Sep 2017 12:34:38 +0300 Subject: [PATCH 02/12] Added function 'print_config()'. Signed-off-by: Ismo Puustinen --- groupcheck.c | 18 +++++++++++++++++- groupcheck.h | 1 + test_groups.c | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/groupcheck.c b/groupcheck.c index 682abca..8e5cbef 100644 --- a/groupcheck.c +++ b/groupcheck.c @@ -214,7 +214,7 @@ bool check_allowed(sd_bus *bus, struct conf_data *conf_data, if (gids[j] == primary_gid) { /* We only include supplementary gids in the check, not the primary gid. This is to make it more difficult for - processes to exec a setgid process to gain elevated + processes to exec a setgid binary to gain elevated group access. */ continue; } @@ -394,6 +394,22 @@ void print_decision(struct subject *subject, const char *action_id, bool allowed } } +void print_config(struct conf_data *conf_data) +{ + int i, j; + + if (conf_data == NULL) + return; + + for (i = 0; i < conf_data->n_lines; i++) { + fprintf(stdout, "id: %s, groups: ", conf_data->lines[i].id); + for (j = 0; j < conf_data->lines[i].n_groups; j++) { + fprintf(stdout, "%s ", conf_data->lines[i].groups[j]); + } + fprintf(stdout, "\n"); + } +} + static int method_check_authorization(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { int r; diff --git a/groupcheck.h b/groupcheck.h index 4c9e01b..24583fe 100644 --- a/groupcheck.h +++ b/groupcheck.h @@ -75,4 +75,5 @@ int load_directory(struct conf_data *conf_data, const char *filename); /* Exported for test programs. */ void print_decision(struct subject *subject, const char *action_id, bool allowed); +void print_config(struct conf_data *conf_data); bool check_allowed(sd_bus *bus, struct conf_data *conf_data, struct subject *subject, const char *action_id); diff --git a/test_groups.c b/test_groups.c index e3aaee2..a0902c8 100644 --- a/test_groups.c +++ b/test_groups.c @@ -45,6 +45,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Error loading policy data.\n"); goto end; } + print_config(&conf_data); subject.kind = SUBJECT_KIND_UNIX_PROCESS; subject.data.p.pid = getpid(); From 4ac5b5e0c00e639c97e1b9c23b519f8c9babec47 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Mon, 11 Sep 2017 15:53:09 +0300 Subject: [PATCH 03/12] Redid start time parsing. Signed-off-by: Ismo Puustinen --- groupcheck.c | 29 ++++++++++++++++++++++++----- groupcheck.h | 1 + test_groups.c | 6 +++++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/groupcheck.c b/groupcheck.c index 8e5cbef..a29d8d2 100644 --- a/groupcheck.c +++ b/groupcheck.c @@ -31,10 +31,9 @@ #define STAT_NAME_SIZE 32 #define STAT_DATA_SIZE 256 -static int verify_start_time(struct subject *subject) +int get_start_time(pid_t pid, uint64_t *start) { - /* Get the pid start time from /proc/stat and compare it with the value in - * the request. Return -1 if no match. */ + /* Get the pid start time from /proc/stat. */ char namebuf[STAT_NAME_SIZE]; char databuf[STAT_DATA_SIZE]; @@ -44,7 +43,7 @@ static int verify_start_time(struct subject *subject) int i; uint64_t start_time; - r = snprintf(namebuf, STAT_NAME_SIZE, "/proc/%d/stat", subject->data.p.pid); + r = snprintf(namebuf, STAT_NAME_SIZE, "/proc/%d/stat", pid); if (r < 0 || r >= STAT_NAME_SIZE) return -EINVAL; @@ -64,6 +63,7 @@ static int verify_start_time(struct subject *subject) if (*p == '\0') return -EINVAL; + p++; /* That was the second field. Then skip over 19 more (20 spaces). */ @@ -71,12 +71,31 @@ static int verify_start_time(struct subject *subject) p = strchr(p, ' '); if (*p == '\0') return -EINVAL; + p++; } start_time = strtoul(p, &endp, 10); - if (endp != NULL) + + if (endp == NULL || *endp != ' ') return -EINVAL; + *start = start_time; + + return 0; +} + +static int verify_start_time(struct subject *subject) +{ + int r; + uint64_t start_time = 0; + + /* Compare pid start time with the value in the request. Return -1 + * if no match. */ + + r = get_start_time(subject->data.p.pid, &start_time); + if (r < 0) + return r; + if (start_time != subject->data.p.start_time) return -EINVAL; diff --git a/groupcheck.h b/groupcheck.h index 24583fe..23f9871 100644 --- a/groupcheck.h +++ b/groupcheck.h @@ -74,6 +74,7 @@ int load_file(struct conf_data *conf_data, const char *filename); int load_directory(struct conf_data *conf_data, const char *filename); /* Exported for test programs. */ +int get_start_time(pid_t pid, uint64_t *start); void print_decision(struct subject *subject, const char *action_id, bool allowed); void print_config(struct conf_data *conf_data); bool check_allowed(sd_bus *bus, struct conf_data *conf_data, struct subject *subject, const char *action_id); diff --git a/test_groups.c b/test_groups.c index a0902c8..0727522 100644 --- a/test_groups.c +++ b/test_groups.c @@ -49,7 +49,11 @@ int main(int argc, char *argv[]) subject.kind = SUBJECT_KIND_UNIX_PROCESS; subject.data.p.pid = getpid(); - subject.data.p.start_time = 0; + r = get_start_time(subject.data.p.pid, &subject.data.p.start_time); + if (r < 0) { + fprintf(stderr, "Error obtaining process start time.\n"); + goto end; + } allowed = check_allowed(NULL, &conf_data, &subject, action_id); print_decision(&subject, action_id, allowed); From f2ff76431b222a49f39b4e6356fe42eba63e3634 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Mon, 11 Sep 2017 15:53:52 +0300 Subject: [PATCH 04/12] D-Bus testing. Signed-off-by: Ismo Puustinen --- Makefile.am | 12 ++- meson.build | 3 +- test_bus.c | 142 ++++++++++++++++++++++++++++++++ test_groups.c => test_process.c | 0 4 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 test_bus.c rename test_groups.c => test_process.c (100%) diff --git a/Makefile.am b/Makefile.am index 90c5acc..85bf47f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,10 +3,14 @@ groupcheck_SOURCES = groupcheck.c main.c groupcheck_CPPFLAGS = $(LIBSYSTEMD_CPPFLAGS) groupcheck_LDADD = $(LIBSYSTEMD_LIBS) -noinst_PROGRAMS = test_groups test_directory -test_groups_SOURCES = groupcheck.c test_groups.c -test_groups_CPPFLAGS = $(LIBSYSTEMD_CPPFLAGS) -test_groups_LDADD = $(LIBSYSTEMD_LIBS) +noinst_PROGRAMS = test_process test_directory test_bus +test_process_SOURCES = groupcheck.c test_process.c +test_process_CPPFLAGS = $(LIBSYSTEMD_CPPFLAGS) +test_process_LDADD = $(LIBSYSTEMD_LIBS) + +test_bus_SOURCES = groupcheck.c test_bus.c +test_bus_CPPFLAGS = $(LIBSYSTEMD_CPPFLAGS) +test_bus_LDADD = $(LIBSYSTEMD_LIBS) test_directory_SOURCES = groupcheck.c test_directory.c test_directory_CPPFLAGS = $(LIBSYSTEMD_CPPFLAGS) diff --git a/meson.build b/meson.build index b2ee0c8..caa5aaa 100644 --- a/meson.build +++ b/meson.build @@ -4,5 +4,6 @@ systemd = dependency('libsystemd') executable('groupcheck', 'groupcheck.c', 'main.c', dependencies : systemd, install : true) -executable('test-groups', 'groupcheck.c', 'test_groups.c', dependencies : systemd) +executable('test-process', 'groupcheck.c', 'test_process.c', dependencies : systemd) +executable('test-bus', 'groupcheck.c', 'test_bus.c', dependencies : systemd) executable('test-directory', 'groupcheck.c', 'test_directory.c', dependencies : systemd) diff --git a/test_bus.c b/test_bus.c new file mode 100644 index 0000000..cd0a60a --- /dev/null +++ b/test_bus.c @@ -0,0 +1,142 @@ +/* + * groupcheck is a minimal polkit replacement for group-based authentication. + * Copyright (c) 2016, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "groupcheck.h" + +int main(int argc, char *argv[]) +{ + sd_bus *bus = NULL; + sd_bus_message *msg = NULL, *reply = NULL; + int r = -1; + const char *action_id; + const char *name = NULL; + bool *allowed; + + if (argc != 2) { + fprintf(stderr, "Usage:\n\ttest_bus \n"); + return EXIT_FAILURE; + } + + action_id = argv[1]; + + r = sd_bus_open_system(&bus); + if (r < 0) { + fprintf(stderr, "Error connecting to the system bus: %s\n", strerror(-r)); + goto end; + } + + r = sd_bus_get_unique_name(bus, &name); + if (r < 0) { + fprintf(stderr, "Error getting unique name: %s\n", strerror(-r)); + goto end; + } + + r = sd_bus_message_new_method_call(bus, + &msg, + "org.freedesktop.PolicyKit1", + "/org/freedesktop/PolicyKit1/Authority", + "org.freedesktop.PolicyKit1.Authority", + "CheckAuthorization"); + if (r < 0) { + fprintf(stderr, "Error creating method call: %s\n", strerror(-r)); + goto end; + } + + r = sd_bus_message_open_container(msg, SD_BUS_TYPE_STRUCT, "sa{sv}"); + + r = sd_bus_message_append(msg, "s", "system-bus-name"); + if (r < 0) + goto end; + + r = sd_bus_message_open_container(msg, SD_BUS_TYPE_ARRAY, "{sv}"); + if (r < 0) + goto end; + + r = sd_bus_message_open_container(msg, SD_BUS_TYPE_DICT_ENTRY, "sv"); + if (r < 0) + goto end; + + r = sd_bus_message_append(msg, "s", "name"); + if (r < 0) + goto end; + + r = sd_bus_message_append(msg, "v", "s", name); + if (r < 0) + goto end; + + /* dict entry */ + r = sd_bus_message_close_container(msg); + if (r < 0) + goto end; + + /* array */ + r = sd_bus_message_close_container(msg); + if (r < 0) + goto end; + + /* struct */ + r = sd_bus_message_close_container(msg); + if (r < 0) + goto end; + + r = sd_bus_message_append(msg, "s", action_id); + if (r < 0) + goto end; + + r = sd_bus_message_append(msg, "a{ss}", 0, NULL); + if (r < 0) + goto end; + + r = sd_bus_message_append(msg, "u", 1); + if (r < 0) + goto end; + + r = sd_bus_message_append(msg, "s", ""); + if (r < 0) + goto end; + + r = sd_bus_call(bus, msg, 0, NULL, &reply); + if (r < 0) { + fprintf(stderr, "D-Bus method call failed: %s\n", strerror(-r)); + goto end; + } + + r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_STRUCT, "bba{ss}"); + if (r < 0) + return r; + + r = sd_bus_message_read(reply, "b", &allowed); + if (r < 0) + return r; + + printf("Permission was %sgranted\n", allowed ? "" : "NOT "); + +end: + + if (r < 0) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/test_groups.c b/test_process.c similarity index 100% rename from test_groups.c rename to test_process.c From cc4b784459846e37e4cf1c892f63a9562adfa372 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Mon, 11 Sep 2017 15:54:56 +0300 Subject: [PATCH 05/12] Service: use new command line syntax. Signed-off-by: Ismo Puustinen --- groupcheck.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groupcheck.service b/groupcheck.service index 5bc370f..b712bd3 100644 --- a/groupcheck.service +++ b/groupcheck.service @@ -5,7 +5,7 @@ Description=groupcheck -- minimal polkit replacement User=groupcheck Type=dbus BusName=org.freedesktop.PolicyKit1 -ExecStart=/usr/sbin/groupcheck +ExecStart=/usr/sbin/groupcheck -f /etc/groupcheck/groupcheck.policy [Install] WantedBy=multi-user.target From ec047e7af9ebc9b4f0837c9eb8545cb2a56f6640 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Mon, 11 Sep 2017 16:05:06 +0300 Subject: [PATCH 06/12] Query effective UID from bus credentials. Nowadays effective UID needs to be indenpendently defined in the query mask. Signed-off-by: Ismo Puustinen --- groupcheck.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/groupcheck.c b/groupcheck.c index a29d8d2..b66d025 100644 --- a/groupcheck.c +++ b/groupcheck.c @@ -112,7 +112,8 @@ bool check_allowed(sd_bus *bus, struct conf_data *conf_data, sd_bus_creds *creds = NULL; gid_t primary_gid; uint64_t mask = SD_BUS_CREDS_SUPPLEMENTARY_GIDS | SD_BUS_CREDS_AUGMENT - | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID | SD_BUS_CREDS_UID; + | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID | SD_BUS_CREDS_UID + | SD_BUS_CREDS_EUID; const gid_t *gids = NULL; int n_gids = 0; uid_t ruid, euid; From adee52d7ee3bbf8e9a4e02229ba2f593abb37bac Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Mon, 11 Sep 2017 16:19:48 +0300 Subject: [PATCH 07/12] Test cleanups and comments. Signed-off-by: Ismo Puustinen --- test_bus.c | 6 ++++-- test_process.c | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test_bus.c b/test_bus.c index cd0a60a..faa45ad 100644 --- a/test_bus.c +++ b/test_bus.c @@ -17,10 +17,8 @@ #include #include #include -#include #include -#include #include "groupcheck.h" @@ -33,6 +31,8 @@ int main(int argc, char *argv[]) const char *name = NULL; bool *allowed; + /* TODO: set supplementary groups to a set we want to test. */ + if (argc != 2) { fprintf(stderr, "Usage:\n\ttest_bus \n"); return EXIT_FAILURE; @@ -64,6 +64,8 @@ int main(int argc, char *argv[]) } r = sd_bus_message_open_container(msg, SD_BUS_TYPE_STRUCT, "sa{sv}"); + if (r < 0) + goto end; r = sd_bus_message_append(msg, "s", "system-bus-name"); if (r < 0) diff --git a/test_process.c b/test_process.c index 0727522..4525142 100644 --- a/test_process.c +++ b/test_process.c @@ -32,6 +32,8 @@ int main(int argc, char *argv[]) struct subject subject; bool allowed; + /* TODO: set supplementary groups to a set we want to test. */ + if (argc != 3) { fprintf(stderr, "Usage:\n\ttest_groups \n"); return EXIT_FAILURE; From c04d86a2ef59ea6834e5342dcc5369fb4e2a8859 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Mon, 11 Sep 2017 16:28:54 +0300 Subject: [PATCH 08/12] Meson: install binary to $prefix/sbin/ Signed-off-by: Ismo Puustinen --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index caa5aaa..8f20774 100644 --- a/meson.build +++ b/meson.build @@ -2,7 +2,7 @@ project('groupcheck', 'c') systemd = dependency('libsystemd') -executable('groupcheck', 'groupcheck.c', 'main.c', dependencies : systemd, install : true) +executable('groupcheck', 'groupcheck.c', 'main.c', dependencies : systemd, install : true, install_dir : get_option('sbindir')) executable('test-process', 'groupcheck.c', 'test_process.c', dependencies : systemd) executable('test-bus', 'groupcheck.c', 'test_bus.c', dependencies : systemd) From 1eb99e09f8d56d463bf4094ad2bb1631e5fe33a8 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Mon, 11 Sep 2017 16:35:44 +0300 Subject: [PATCH 09/12] Remember to close an opened file. Signed-off-by: Ismo Puustinen --- groupcheck.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/groupcheck.c b/groupcheck.c index b66d025..5931ad5 100644 --- a/groupcheck.c +++ b/groupcheck.c @@ -38,7 +38,7 @@ int get_start_time(pid_t pid, uint64_t *start) char namebuf[STAT_NAME_SIZE]; char databuf[STAT_DATA_SIZE]; int r; - FILE *f; + FILE *f = NULL; char *p, *endp = NULL; int i; uint64_t start_time; @@ -53,35 +53,48 @@ int get_start_time(pid_t pid, uint64_t *start) return -EINVAL; p = fgets(databuf, STAT_DATA_SIZE, f); - if (p == NULL) - return -EINVAL; + if (p == NULL) { + r = -EINVAL; + goto end; + } /* read the 22th field, which is the process start time in jiffies */ /* skip over the "comm" field that has parentheses */ p = strchr(p, ')'); - if (*p == '\0') - return -EINVAL; + if (*p == '\0') { + r = -EINVAL; + goto end; + } p++; /* That was the second field. Then skip over 19 more (20 spaces). */ for (i = 0; i < 20; i++) { p = strchr(p, ' '); - if (*p == '\0') - return -EINVAL; + if (*p == '\0') { + r= -EINVAL; + goto end; + } p++; } start_time = strtoul(p, &endp, 10); - if (endp == NULL || *endp != ' ') - return -EINVAL; + if (endp == NULL || *endp != ' ') { + r = -EINVAL; + goto end; + } *start = start_time; + r = 0; - return 0; +end: + if (f) + fclose(f); + + return r; } static int verify_start_time(struct subject *subject) From aaef3bf75e296b8511302a479424f153b8d42713 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Tue, 12 Sep 2017 09:57:33 +0300 Subject: [PATCH 10/12] Updated version to 2.0. Signed-off-by: Ismo Puustinen --- configure.ac | 2 +- groupcheck.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1c8ff3a..626a3f2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([groupcheck], 0.1) +AC_INIT([groupcheck], 2.0) AM_INIT_AUTOMAKE AC_PROG_CC AC_CONFIG_FILES(Makefile) diff --git a/groupcheck.c b/groupcheck.c index 5931ad5..4d2d989 100644 --- a/groupcheck.c +++ b/groupcheck.c @@ -645,7 +645,7 @@ static int property_backend_version(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) { - return sd_bus_message_append(reply, "s", "0.1"); + return sd_bus_message_append(reply, "s", "2.0"); } static int property_backend_features(sd_bus *bus, const char *path, From 727e1d5fe4bb5f8329af0669863fe43cc770459c Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Tue, 12 Sep 2017 12:33:48 +0300 Subject: [PATCH 11/12] Align test binary names for meson and autotools. Signed-off-by: Ismo Puustinen --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 85bf47f..fdcc199 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,7 @@ groupcheck_SOURCES = groupcheck.c main.c groupcheck_CPPFLAGS = $(LIBSYSTEMD_CPPFLAGS) groupcheck_LDADD = $(LIBSYSTEMD_LIBS) -noinst_PROGRAMS = test_process test_directory test_bus +noinst_PROGRAMS = test-process test-directory test-bus test_process_SOURCES = groupcheck.c test_process.c test_process_CPPFLAGS = $(LIBSYSTEMD_CPPFLAGS) test_process_LDADD = $(LIBSYSTEMD_LIBS) From 32e11bbc4bc031ee2065b7bb3ff421255a365b30 Mon Sep 17 00:00:00 2001 From: Ismo Puustinen Date: Tue, 12 Sep 2017 14:42:00 +0300 Subject: [PATCH 12/12] Tests accept supplementary groups from command line. Tests now accept a list of supplementary groups as parameters to the command line. For example, you can call test-bus with a list of group parameters: sudo test-bus org.freedesktop.fwupd.update-hotplug-trusted hotplug wheel Here the "hotplug" and "wheel" parameters are the supplementary groups which are added to the process. Sudo is needed so that the groups can be set (CAP_SETGID would be enough). Signed-off-by: Ismo Puustinen --- test_bus.c | 28 +++++++++++++++++++++++----- test_process.c | 29 ++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/test_bus.c b/test_bus.c index faa45ad..006c373 100644 --- a/test_bus.c +++ b/test_bus.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include @@ -26,20 +28,36 @@ int main(int argc, char *argv[]) { sd_bus *bus = NULL; sd_bus_message *msg = NULL, *reply = NULL; - int r = -1; + int r = -1, i; const char *action_id; const char *name = NULL; bool *allowed; + gid_t supplementary_groups[argc]; - /* TODO: set supplementary groups to a set we want to test. */ - - if (argc != 2) { - fprintf(stderr, "Usage:\n\ttest_bus \n"); + if (argc < 2) { + fprintf(stderr, "Usage:\n\ttest_bus [group1 group2 ...]\n"); return EXIT_FAILURE; } action_id = argv[1]; + if (argc > 2) { + for (i = 0; i < argc-2; i++) { + struct group *grp; + grp = getgrnam(argv[i+2]); + if (grp == NULL) { + fprintf(stderr, "Error: group '%s' was not found.\n", argv[i+2]); + goto end; + } + supplementary_groups[i] = grp->gr_gid; + } + r = setgroups(argc-2, supplementary_groups); + if (r < 0) { + fprintf(stderr, "Error setting the supplementary groups: %s\n", strerror(errno)); + goto end; + } + } + r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Error connecting to the system bus: %s\n", strerror(-r)); diff --git a/test_process.c b/test_process.c index 4525142..03d9c77 100644 --- a/test_process.c +++ b/test_process.c @@ -17,9 +17,8 @@ #include #include #include - -#include -#include +#include +#include #include "groupcheck.h" @@ -31,17 +30,33 @@ int main(int argc, char *argv[]) struct conf_data conf_data = { 0 }; struct subject subject; bool allowed; + gid_t supplementary_groups[argc]; - /* TODO: set supplementary groups to a set we want to test. */ - - if (argc != 3) { - fprintf(stderr, "Usage:\n\ttest_groups \n"); + if (argc < 3) { + fprintf(stderr, "Usage:\n\ttest_groups [group1 group2 ...]\n"); return EXIT_FAILURE; } policy_file = argv[1]; action_id = argv[2]; + if (argc > 3) { + for (i = 0; i < argc-3; i++) { + struct group *grp; + grp = getgrnam(argv[i+3]); + if (grp == NULL) { + fprintf(stderr, "Error: group '%s' was not found.\n", argv[i+3]); + goto end; + } + supplementary_groups[i] = grp->gr_gid; + } + r = setgroups(argc-3, supplementary_groups); + if (r < 0) { + fprintf(stderr, "Error setting the supplementary groups: %s\n", strerror(errno)); + goto end; + } + } + r = load_file(&conf_data, policy_file); if (r < 0) { fprintf(stderr, "Error loading policy data.\n");