On Tue, Oct 14, 2014 at 06:22:05PM +0200, Pavel Reichl wrote: > > On 10/13/2014 04:08 PM, Jakub Hrozek wrote: > >Hi, > > > >I guess I can safely send another round of patches that were already > >tested by Michal and me. > > > >The first patch adds new command line options --uid and --gid to all SSSD > >servers, making it possible to switch to another user ID if needed. So > >far all the servers still run as root. > > > >The other patches are trivial refactoring for unit tests (2 and 3). I > >don't like the #ifdefs in server.c, but I couldn't think of another > >way.. > > > >The final patch is a unit test for server_setup, exercising different > >options. > > > > > >_______________________________________________ > >sssd-devel mailing list > >sssd-devel@lists.fedorahosted.org > >https://lists.fedorahosted.org/mailman/listinfo/sssd-devel > I'm seeing this minor problem: > > ../../../../src/tests/cwrap/../../../src/util/domain_info_utils.c: In > function ‘subdomain_enumerates’: > ../../../../src/tests/cwrap/../../../src/util/domain_info_utils.c:77:9: > error: ‘for’ loop initial declarations are only allowed in C99 mode > for (int i=0; parent->sd_enumerate[i]; i++) { > ^ > ../../../../src/tests/cwrap/../../../src/util/domain_info_utils.c:77:9: > note: use option -std=c99 or -std=gnu99 to compile your code > make[3]: *** [../../../src/util/server_tests-domain_info_utils.o] Error 1
I think your patch addresses a legitimate problem in the old code and should be included separately. ACK to the patch. See the attached patchset..
>From 5feca0de6bf245ffd51f1d476a0db975a69c64a3 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Mon, 6 Oct 2014 16:28:13 +0200 Subject: [PATCH 1/5] SSSD: Add the options to specify a UID and GID to run as Adds new command line options --uid and --gid to all SSSD servers, making it possible to switch to another user ID if needed. So far all code still runs as root. --- Makefile.am | 7 +++++-- src/monitor/monitor.c | 3 ++- src/providers/data_provider_be.c | 5 ++++- src/providers/proxy/proxy_child.c | 5 ++++- src/responder/autofs/autofssrv.c | 6 +++++- src/responder/ifp/ifpsrv.c | 3 ++- src/responder/nss/nsssrv.c | 5 ++++- src/responder/pac/pacsrv.c | 5 ++++- src/responder/pam/pamsrv.c | 5 ++++- src/responder/ssh/sshsrv.c | 5 ++++- src/responder/sudo/sudosrv.c | 6 +++++- src/util/server.c | 8 ++++++++ src/util/util.h | 7 +++++++ 13 files changed, 58 insertions(+), 12 deletions(-) diff --git a/Makefile.am b/Makefile.am index 4ee7eb9b61771edd3207d84c3d6fd980a833ecf1..021498ff5793381397282089d4b44e9bb9bb0e3a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -709,14 +709,17 @@ libsss_util_la_SOURCES = \ src/util/util_sss_idmap.c \ src/util/well_known_sids.c \ src/util/string_utils.c \ + src/util/become_user.c \ $(NULL) libsss_util_la_CFLAGS = \ $(AM_CFLAGS) \ - $(SYSTEMD_LOGIN_CFLAGS) + $(SYSTEMD_LOGIN_CFLAGS) \ + $(NULL) libsss_util_la_LIBADD = \ $(SSSD_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ - $(UNICODE_LIBS) + $(UNICODE_LIBS) \ + $(NULL) if BUILD_SUDO libsss_util_la_SOURCES += src/db/sysdb_sudo.c endif diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 624e45026b01842ab81d8c37d50751977185d20c..edd1c2dfc674d8a7ca9d069d6499c0dcc959f210 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -2855,7 +2855,8 @@ int main(int argc, const char *argv[]) ret = close(STDIN_FILENO); if (ret != EOK) return 6; - ret = server_setup(MONITOR_NAME, flags, monitor->conf_path, &main_ctx); + ret = server_setup(MONITOR_NAME, flags, 0, 0, + monitor->conf_path, &main_ctx); if (ret != EOK) return 2; monitor->is_daemon = !opt_interactive; diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index e7f345f922361b60775e149c1b28f45cf16ed00e..18b50214b0795709d583d5891bf4f6fd220bcb11 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -2804,10 +2804,13 @@ int main(int argc, const char *argv[]) struct main_context *main_ctx; char *confdb_path; int ret; + uid_t uid; + gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS + SSSD_SERVER_OPTS(uid, gid) {"domain", 0, POPT_ARG_STRING, &be_domain, 0, _("Domain of the information provider (mandatory)"), NULL }, POPT_TABLEEND @@ -2847,7 +2850,7 @@ int main(int argc, const char *argv[]) confdb_path = talloc_asprintf(NULL, CONFDB_DOMAIN_PATH_TMPL, be_domain); if (!confdb_path) return 2; - ret = server_setup(srv_name, 0, confdb_path, &main_ctx); + ret = server_setup(srv_name, 0, 0, 0, confdb_path, &main_ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up mainloop [%d]\n", ret); return 2; diff --git a/src/providers/proxy/proxy_child.c b/src/providers/proxy/proxy_child.c index 6bee1c7f63c4bb5b33f11601c2be32df05206756..e261b2f588a89a27ed6fe78f7fc5cfa053b49833 100644 --- a/src/providers/proxy/proxy_child.c +++ b/src/providers/proxy/proxy_child.c @@ -504,10 +504,13 @@ int main(int argc, const char *argv[]) int ret; long id; char *pam_target = NULL; + uid_t uid; + gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS + SSSD_SERVER_OPTS(uid, gid) {"domain", 0, POPT_ARG_STRING, &domain, 0, _("Domain of the information provider (mandatory)"), NULL }, {"id", 0, POPT_ARG_LONG, &id, 0, @@ -557,7 +560,7 @@ int main(int argc, const char *argv[]) conf_entry = talloc_asprintf(NULL, CONFDB_DOMAIN_PATH_TMPL, domain); if (!conf_entry) return 2; - ret = server_setup(srv_name, 0, conf_entry, &main_ctx); + ret = server_setup(srv_name, 0, 0, 0, conf_entry, &main_ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up mainloop [%d]\n", ret); return 2; diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c index bd5aa135a3fb64a020e74a9dd39fa1b67dc76533..931cf018bfe15b37bf8e5f93a21c7ab61d238c18 100644 --- a/src/responder/autofs/autofssrv.c +++ b/src/responder/autofs/autofssrv.c @@ -207,10 +207,13 @@ int main(int argc, const char *argv[]) poptContext pc; struct main_context *main_ctx; int ret; + uid_t uid; + gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS + SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; @@ -235,7 +238,8 @@ int main(int argc, const char *argv[]) /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_autofs"; - ret = server_setup("sssd[autofs]", 0, CONFDB_AUTOFS_CONF_ENTRY, &main_ctx); + ret = server_setup("sssd[autofs]", 0, 0, 0, + CONFDB_AUTOFS_CONF_ENTRY, &main_ctx); if (ret != EOK) { return 2; } diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c index 4af836543d3945603d22099b7ab98a90588bce35..6413c18c8943f1d8bb213605073acc50996210ca 100644 --- a/src/responder/ifp/ifpsrv.c +++ b/src/responder/ifp/ifpsrv.c @@ -469,7 +469,8 @@ int main(int argc, const char *argv[]) /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_ifp"; - ret = server_setup("sssd[ifp]", 0, CONFDB_IFP_CONF_ENTRY, &main_ctx); + ret = server_setup("sssd[ifp]", 0, 0, 0, + CONFDB_IFP_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; ret = die_if_parent_died(); diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c index 84a6b7fedd096a7d4159b7ac6670820c1d8fd941..420fd3d316959a67737f23e9a8b3d1c797583ea3 100644 --- a/src/responder/nss/nsssrv.c +++ b/src/responder/nss/nsssrv.c @@ -537,10 +537,13 @@ int main(int argc, const char *argv[]) poptContext pc; struct main_context *main_ctx; int ret; + uid_t uid; + gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS + SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; @@ -565,7 +568,7 @@ int main(int argc, const char *argv[]) /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_nss"; - ret = server_setup("sssd[nss]", 0, CONFDB_NSS_CONF_ENTRY, &main_ctx); + ret = server_setup("sssd[nss]", 0, 0, 0, CONFDB_NSS_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; ret = die_if_parent_died(); diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c index 47a9d1a68fbf1615277af41cef297b4955e7f7c3..b76691de829b4f40937a07ea83825a606950aa1e 100644 --- a/src/responder/pac/pacsrv.c +++ b/src/responder/pac/pacsrv.c @@ -216,10 +216,13 @@ int main(int argc, const char *argv[]) poptContext pc; struct main_context *main_ctx; int ret; + uid_t uid; + gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS + SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; @@ -244,7 +247,7 @@ int main(int argc, const char *argv[]) /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_pac"; - ret = server_setup("sssd[pac]", 0, CONFDB_PAC_CONF_ENTRY, &main_ctx); + ret = server_setup("sssd[pac]", 0, 0, 0, CONFDB_PAC_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; ret = die_if_parent_died(); diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c index 428b252acb56406291e3cac5d2a13e6f6b581c36..91b395080820b27f5d57341e59dd739e674be31a 100644 --- a/src/responder/pam/pamsrv.c +++ b/src/responder/pam/pamsrv.c @@ -316,10 +316,13 @@ int main(int argc, const char *argv[]) poptContext pc; struct main_context *main_ctx; int ret; + uid_t uid; + gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS + SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; @@ -344,7 +347,7 @@ int main(int argc, const char *argv[]) /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_pam"; - ret = server_setup("sssd[pam]", 0, CONFDB_PAM_CONF_ENTRY, &main_ctx); + ret = server_setup("sssd[pam]", 0, 0, 0, CONFDB_PAM_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; ret = die_if_parent_died(); diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c index 8aa603d79dddb327606f02d9e7ddf2b18a98e700..1328d1746b9e2d6474d6c2f8ce2825be463ca3e7 100644 --- a/src/responder/ssh/sshsrv.c +++ b/src/responder/ssh/sshsrv.c @@ -184,10 +184,13 @@ int main(int argc, const char *argv[]) poptContext pc; struct main_context *main_ctx; int ret; + uid_t uid; + gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS + SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; @@ -212,7 +215,7 @@ int main(int argc, const char *argv[]) /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_ssh"; - ret = server_setup("sssd[ssh]", 0, CONFDB_SSH_CONF_ENTRY, &main_ctx); + ret = server_setup("sssd[ssh]", 0, 0, 0, CONFDB_SSH_CONF_ENTRY, &main_ctx); if (ret != EOK) { return 2; } diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c index 8a197159b23abde45953b65121ff2e3fc3f2f67a..30752c9dacdc390b24fe837c0630333b5e171448 100644 --- a/src/responder/sudo/sudosrv.c +++ b/src/responder/sudo/sudosrv.c @@ -164,10 +164,13 @@ int main(int argc, const char *argv[]) poptContext pc; struct main_context *main_ctx; int ret; + uid_t uid; + gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS + SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; @@ -192,7 +195,8 @@ int main(int argc, const char *argv[]) /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_sudo"; - ret = server_setup("sssd[sudo]", 0, CONFDB_SUDO_CONF_ENTRY, &main_ctx); + ret = server_setup("sssd[sudo]", 0, 0, 0, CONFDB_SUDO_CONF_ENTRY, + &main_ctx); if (ret != EOK) { return 2; } diff --git a/src/util/server.c b/src/util/server.c index 51934f8ba287d6f6e395231ed893753e10b4c9b0..3a84dee0cee06cb98c94a1d57209c2bcf7c4340a 100644 --- a/src/util/server.c +++ b/src/util/server.c @@ -412,6 +412,7 @@ errno_t server_common_rotate_logs(struct confdb_ctx *confdb, } int server_setup(const char *name, int flags, + uid_t uid, gid_t gid, const char *conf_entry, struct main_context **main_ctx) { @@ -426,6 +427,13 @@ int server_setup(const char *name, int flags, struct tevent_signal *tes; struct logrotate_ctx *lctx; + ret = become_user(uid, gid); + if (ret != EOK) { + DEBUG(SSSDBG_FUNC_DATA, + "Cannot become user [%"SPRIuid"][%"SPRIgid"].\n", uid, gid); + return ret; + } + debug_prg_name = strdup(name); if (!debug_prg_name) { return ENOMEM; diff --git a/src/util/util.h b/src/util/util.h index c497f605bb58a6acba45c64399a05cc3539b4263..0d7a2daa3bbcc9b8a86681c119bec8d556fcde49 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -175,6 +175,12 @@ errno_t set_debug_file_from_fd(const int fd); #define SSSD_MAIN_OPTS SSSD_DEBUG_OPTS +#define SSSD_SERVER_OPTS(uid, gid) \ + {"uid", 0, POPT_ARG_INT, &uid, 0, \ + _("The user ID to run the server as"), NULL}, \ + {"gid", 0, POPT_ARG_INT, &gid, 0, \ + _("The group ID to run the server as"), NULL}, + #define FLAGS_NONE 0x0000 #define FLAGS_DAEMON 0x0001 #define FLAGS_INTERACTIVE 0x0002 @@ -242,6 +248,7 @@ errno_t server_common_rotate_logs(struct confdb_ctx *confdb, int die_if_parent_died(void); int pidfile(const char *path, const char *name); int server_setup(const char *name, int flags, + uid_t uid, gid_t gid, const char *conf_entry, struct main_context **main_ctx); void server_loop(struct main_context *main_ctx); -- 1.9.3
>From d779d2b648b89f9b1fe3e0f1cffe1a67131f18e0 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Fri, 3 Oct 2014 16:09:38 +0200 Subject: [PATCH 2/5] UTIL: Use a custom PID_PATH and DB_PATH when unit testing server.c server.c used hardcoded PID_PATH and DB_PATH from config.h. Normally, this path resides in a system directory (like /var/) and should not be written to by tests. In order to specify a different one for tests, we need to conditionalize normal builds and unit test builds. --- src/util/server.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/util/server.c b/src/util/server.c index 3a84dee0cee06cb98c94a1d57209c2bcf7c4340a..742a712aef8bd859733362c9ca82464bcb36cfcf 100644 --- a/src/util/server.c +++ b/src/util/server.c @@ -411,6 +411,32 @@ errno_t server_common_rotate_logs(struct confdb_ctx *confdb, return EOK; } +static const char *get_db_path(void) +{ +#ifdef UNIT_TESTING +#ifdef TEST_DB_PATH + return TEST_DB_PATH; +#else + #error "TEST_DB_PATH must be defined when unit testing server.c!" +#endif /* TEST_DB_PATH */ +#else + return DB_PATH; +#endif /* UNIT_TESTING */ +} + +static const char *get_pid_path(void) +{ +#ifdef UNIT_TESTING +#ifdef TEST_PID_PATH + return TEST_PID_PATH; +#else + #error "TEST_PID_PATH must be defined when unit testing server.c!" +#endif /* TEST_PID_PATH */ +#else + return PID_PATH; +#endif +} + int server_setup(const char *name, int flags, uid_t uid, gid_t gid, const char *conf_entry, @@ -462,10 +488,10 @@ int server_setup(const char *name, int flags, } if (flags & FLAGS_PID_FILE) { - ret = pidfile(PID_PATH, name); + ret = pidfile(get_pid_path(), name); if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "Error creating pidfile: %s/%s! " - "(%d [%s])\n", PID_PATH, name, ret, strerror(ret)); + DEBUG(SSSDBG_FATAL_FAILURE, "Error creating pidfile: %s/%s.pid! " + "(%d [%s])\n", get_pid_path(), name, ret, strerror(ret)); return ret; } } @@ -507,7 +533,8 @@ int server_setup(const char *name, int flags, ctx->parent_pid = getppid(); ctx->event_ctx = event_ctx; - conf_db = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE); + conf_db = talloc_asprintf(ctx, "%s/%s", + get_db_path(), CONFDB_FILE); if (conf_db == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory, aborting!\n"); return ENOMEM; -- 1.9.3
>From 19a3cb234f75ae7abb0540c7c8a00b0a700f46ac Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Fri, 3 Oct 2014 16:11:08 +0200 Subject: [PATCH 3/5] TESTS: Unit tests can use confdb without using sysdb Previously, if a test used the utility functions for setting up a test, it had to use both sysdb and confdb. Some unit tests only need to use of of them, for example the unit tests for the server module only need confdb. --- src/tests/common_dom.c | 52 +++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/tests/common_dom.c b/src/tests/common_dom.c index b96db8d9084fea9ec07be88d9c5f72c6885d8f09..bc69c5a093e17fc56e42ccedd998ab6434d85003 100644 --- a/src/tests/common_dom.c +++ b/src/tests/common_dom.c @@ -159,34 +159,38 @@ void test_dom_suite_cleanup(const char *tests_path, return; } - conf_db = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, confdb_path); - if (!conf_db) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not construct conf_db path\n"); - goto done; - } + if (confdb_path != NULL) { + conf_db = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, confdb_path); + if (!conf_db) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not construct conf_db path\n"); + goto done; + } - errno = 0; - ret = unlink(conf_db); - if (ret != 0 && errno != ENOENT) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not delete the test config ldb file (%d) (%s)\n", - errno, strerror(errno)); + errno = 0; + ret = unlink(conf_db); + if (ret != 0 && errno != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not delete the test config ldb file (%d) (%s)\n", + errno, strerror(errno)); + } } - sys_db = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, sysdb_path); - if (!sys_db) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not construct sys_db path\n"); - goto done; - } + if (sysdb_path != NULL) { + sys_db = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, sysdb_path); + if (!sys_db) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not construct sys_db path\n"); + goto done; + } - errno = 0; - ret = unlink(sys_db); - if (ret != 0 && errno != ENOENT) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not delete the test ldb file (%d) (%s)\n", - errno, strerror(errno)); + errno = 0; + ret = unlink(sys_db); + if (ret != 0 && errno != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not delete the test ldb file (%d) (%s)\n", + errno, strerror(errno)); + } } errno = 0; -- 1.9.3
>From 7c38b9be0f0f25d2192b9ea7f846067dcff3f19f Mon Sep 17 00:00:00 2001 From: Pavel Reichl <prei...@redhat.com> Date: Tue, 14 Oct 2014 18:02:47 +0100 Subject: [PATCH 4/5] TESTS: Add -std=gnu99 to cwrap tests CFLAGS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ../../../../src/tests/cwrap/../../../src/util/domain_info_utils.c: In function ‘subdomain_enumerates’: ../../../../src/tests/cwrap/../../../src/util/domain_info_utils.c:77:9: error: ‘for’ loop initial declarations are only allowed in C99 mode for (int i=0; parent->sd_enumerate[i]; i++) { ^ ../../../../src/tests/cwrap/../../../src/util/domain_info_utils.c:77:9: note: use option -std=c99 or -std=gnu99 to compile your code make[3]: *** [../../../src/util/server_tests-domain_info_utils.o] Error 1 --- src/tests/cwrap/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am index 34aec92c197a60c47067c72df9c8f3644e1a3c45..96b9a52435d9e80bea3ec132cc86c3e6abd0adf2 100644 --- a/src/tests/cwrap/Makefile.am +++ b/src/tests/cwrap/Makefile.am @@ -1,4 +1,5 @@ AM_CPPFLAGS = \ + -std=gnu99 \ -Wall \ -I$(top_srcdir)/src \ -I. \ -- 1.9.3
>From 066199518365a588c9e62a6c8336ea3ba4fde8fc Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Fri, 3 Oct 2014 16:12:01 +0200 Subject: [PATCH 5/5] TESTS: Unit tests for server_setup We changed server_setup, so we must make sure the function continues to work as expected. --- src/tests/cwrap/Makefile.am | 62 ++++++++++++- src/tests/cwrap/test_server.c | 204 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 src/tests/cwrap/test_server.c diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am index 96b9a52435d9e80bea3ec132cc86c3e6abd0adf2..3fb30b28c0e94ac9a447a92bfaf1bfcc1013fd57 100644 --- a/src/tests/cwrap/Makefile.am +++ b/src/tests/cwrap/Makefile.am @@ -3,7 +3,10 @@ AM_CPPFLAGS = \ -Wall \ -I$(top_srcdir)/src \ -I. \ + -DLOCALEDIR=\"$(localedir)\" \ + -DVARDIR=\"$(localstatedir)\" \ $(DBUS_CFLAGS) \ + $(GLIB2_CFLAGS) \ $(NULL) TESTS_ENVIRONMENT = \ @@ -16,6 +19,20 @@ dist_noinst_SCRIPTS = \ cwrap_test_setup.sh \ $(NULL) +SSSD_LIBS = \ + $(TALLOC_LIBS) \ + $(TEVENT_LIBS) \ + $(POPT_LIBS) \ + $(LDB_LIBS) \ + $(DBUS_LIBS) \ + $(PCRE_LIBS) \ + $(INI_CONFIG_LIBS) \ + $(COLLECTION_LIBS) \ + $(DHASH_LIBS) \ + $(SSS_CRYPT_LIBS) \ + $(OPENLDAP_LIBS) \ + $(TDB_LIBS) + dist_noinst_DATA = \ group \ passwd \ @@ -25,7 +42,10 @@ check_PROGRAMS = if HAVE_CMOCKA if HAVE_NSS_WRAPPER if HAVE_UID_WRAPPER -check_PROGRAMS += become_user-tests +check_PROGRAMS = \ + become_user-tests \ + server-tests \ + $(NULL) endif # HAVE_UID_WRAPPER endif # HAVE_NSS_WRAPPER endif # HAVE_CMOCKA @@ -45,4 +65,44 @@ become_user_tests_LDADD = \ $(abs_top_builddir)/libsss_test_common.la \ $(NULL) +server_tests_SOURCES = \ + test_server.c \ + ../../../src/util/server.c \ + ../../../src/util/become_user.c \ + ../../../src/util/backup_file.c \ + ../../../src/util/domain_info_utils.c \ + ../../../src/util/atomic_io.c \ + ../../../src/util/signal.c \ + ../../../src/util/util.c \ + ../../../src/util/strtonum.c \ + ../../../src/util/util_errors.c \ + ../../../src/util/safe-format-string.c \ + ../../../src/util/sss_tc_utf8.c \ + ../../../src/util/sss_utf8.c \ + ../../../src/util/usertools.c \ + ../../../src/confdb/confdb.c \ + ../../../src/db/sysdb.c \ + ../../../src/db/sysdb_upgrade.c \ + ../../../src/db/sysdb_ops.c \ + ../../../src/db/sysdb_search.c \ + ../../../src/db/sysdb_autofs.c \ + ../../../src/db/sysdb_services.c \ + $(NULL) +server_tests_CFLAGS = \ + $(AM_CFLAGS) \ + $(LIBCAPNG_CFLAGS) \ + -DTEST_DB_PATH=\"server_tests\" \ + -DTEST_PID_PATH=\"server_tests\" \ + -DUNIT_TESTING \ + $(NULL) +server_tests_LDADD = \ + $(CMOCKA_LIBS) \ + $(LIBCAPNG_LIBS) \ + $(UNICODE_LIBS) \ + $(SSSD_LIBS) \ + $(abs_top_builddir)/libsss_debug.la \ + $(abs_top_builddir)/libsss_crypt.la \ + $(abs_top_builddir)/libsss_test_common.la \ + $(NULL) + tests: $(check_PROGRAMS) diff --git a/src/tests/cwrap/test_server.c b/src/tests/cwrap/test_server.c new file mode 100644 index 0000000000000000000000000000000000000000..26ecfee1e189b6a474ae52fdbfff6b8922b3f0d7 --- /dev/null +++ b/src/tests/cwrap/test_server.c @@ -0,0 +1,204 @@ +/* + Authors: + Jakub Hrozek <jhro...@redhat.com> + + Copyright (C) 2014 Red Hat + + SSSD tests: Server instantiation + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <popt.h> +#include "util/util.h" +#include "tests/cmocka/common_mock.h" + +static void wait_for_fg_server(pid_t pid) +{ + pid_t wpid; + int status; + + assert_int_not_equal(pid, -1); + + wpid = waitpid(pid, &status, 0); + assert_int_equal(wpid, pid); + assert_true(WIFEXITED(status)); + assert_int_equal(WEXITSTATUS(status), 0); +} + +static void wait_for_bg_server(const char *pidfile) +{ + int fd; + long tmp; + char buf[16]; + pid_t pid; + int ret; + int count; + + count = 0; + do { + struct stat sb; + + count++; + if (count > 100) { + break; + } + + ret = stat(pidfile, &sb); + usleep(50); + } while (ret != 0); + + /* read the pidfile */ + fd = open(pidfile, O_RDONLY); + assert_false(fd < 0); + + ret = read(fd, buf, sizeof(buf)); + close(fd); + assert_false(ret <= 0); + + buf[sizeof(buf) - 1] = '\0'; + + tmp = strtol(buf, NULL, 10); + assert_false(tmp == 0 || tmp > 0xFFFF || errno == ERANGE); + + pid = (pid_t) (tmp & 0xFFFF); + + /* Make sure the daemon goes away! */ + ret = kill(pid, SIGTERM); + fprintf(stderr, "killing %u\n", pid); + assert_true(ret == 0); + + unlink(pidfile); +} + +void test_run_as_root_fg(void **state) +{ + int ret; + struct main_context *main_ctx; + pid_t pid; + + /* Must root as root, real or fake */ + assert_int_equal(geteuid(), 0); + + pid = fork(); + if (pid == 0) { + ret = server_setup(__FUNCTION__, 0, 0, 0, + __FUNCTION__, &main_ctx); + assert_int_equal(ret, 0); + exit(0); + } + wait_for_fg_server(pid); +} + +void test_run_as_sssd_fg(void **state) +{ + int ret; + struct main_context *main_ctx; + struct passwd *sssd; + pid_t pid; + + /* Must root as root, real or fake */ + assert_int_equal(geteuid(), 0); + + sssd = getpwnam("sssd"); + assert_non_null(sssd); + + pid = fork(); + if (pid == 0) { + ret = server_setup(__FUNCTION__, 0, sssd->pw_uid, sssd->pw_gid, + __FUNCTION__, &main_ctx); + assert_int_equal(ret, 0); + exit(0); + } + wait_for_fg_server(pid); +} + +void test_run_as_root_daemon(void **state) +{ + int ret; + struct main_context *main_ctx; + pid_t pid; + char *pidfile; + + /* Must root as root, real or fake */ + assert_int_equal(geteuid(), 0); + + pidfile = talloc_asprintf(NULL, "%s/%s.pid", TEST_PID_PATH, __FUNCTION__); + + /* Make sure there are no leftovers */ + unlink(pidfile); + + pid = fork(); + if (pid == 0) { + ret = server_setup(__FUNCTION__, FLAGS_PID_FILE, + 0, 0, __FUNCTION__, &main_ctx); + assert_int_equal(ret, 0); + + server_loop(main_ctx); + exit(0); + } + + wait_for_bg_server(pidfile); + talloc_free(pidfile); +} + +int main(int argc, const char *argv[]) +{ + poptContext pc; + int opt; + int rv; + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_DEBUG_OPTS + POPT_TABLEEND + }; + + const UnitTest tests[] = { + unit_test(test_run_as_root_fg), + unit_test(test_run_as_sssd_fg), + unit_test(test_run_as_root_daemon), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ + debug_level = SSSDBG_INVALID; + + pc = poptGetContext(argv[0], argc, argv, long_options, 0); + while((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + default: + fprintf(stderr, "\nInvalid option %s: %s\n\n", + poptBadOption(pc, 0), poptStrerror(opt)); + poptPrintUsage(pc, stderr, 0); + return 1; + } + } + poptFreeContext(pc); + + DEBUG_CLI_INIT(debug_level); + + /* Even though normally the tests should clean up after themselves + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + test_dom_suite_cleanup(TEST_DB_PATH, CONFDB_FILE, NULL); + test_dom_suite_setup(TEST_DB_PATH); + + rv = run_tests(tests); + test_dom_suite_cleanup(TEST_DB_PATH, CONFDB_FILE, NULL); + + return rv; +} -- 1.9.3
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel