From 02618c33c2389922a69ebad38a9ee4143d1986a6 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Mon, 9 Feb 2009 13:07:51 -0500 Subject: Adding sysdb_store_group_posix with unit test --- server/Makefile.in | 17 +++-- server/configure.ac | 3 +- server/db/sysdb.c | 172 ++++++++++++++++++++++++++++++++++++++++++++- server/db/sysdb.h | 11 ++- server/nss/nsssrv_cmd.c | 2 +- server/server.mk | 20 ++++-- server/tests/sysdb-tests.c | 165 +++++++++++++++++++++++++++++++++++++++++++ server/util/debug.c | 2 +- 8 files changed, 374 insertions(+), 18 deletions(-) create mode 100644 server/tests/sysdb-tests.c (limited to 'server') diff --git a/server/Makefile.in b/server/Makefile.in index d9fb3f696..917e3fdf4 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -38,6 +38,9 @@ LDB_CFLAGS = @LDB_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_CFLAGS = @DBUS_CFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ + LIBDL = @LIBDL@ SHLIBEXT = @SHLIBEXT@ @@ -46,12 +49,12 @@ LD_EXPORT_DYNAMIC = @LD_EXPORT_DYNAMIC@ SHLD = @SHLD@ SHLD_FLAGS = @SHLD_FLAGS@ -LDFLAGS += @LDFLAGS@ +LDFLAGS += @LDFLAGS@ -L$(srcdir)/lib LIBS = @LIBS@ $(TALLOC_LIBS) $(TDB_LIBS) $(EVENTS_LIBS) $(POPT_LIBS) $(LDB_LIBS) $(DBUS_LIBS) PICFLAG = @PICFLAG@ CFLAGS += -g -I$(srcdir)/include -Iinclude -I$(srcdir) -I$(srcdir)/.. \ - $(POPT_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) $(EVENTS_CFLAGS) $(LDB_CFLAGS) $(DBUS_CFLAGS)\ + $(POPT_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) $(EVENTS_CFLAGS) $(LDB_CFLAGS) $(DBUS_CFLAGS) $(CHECK_CFLAGS)\ -DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"$(SHLIBEXT)\" -DSSSD_LIBEXEC_PATH=\"$(SSSD_LIBEXEC_PATH)\" -DUSE_MMAP=1 @CFLAGS@ MDLD = @MDLD@ @@ -71,21 +74,24 @@ DBUS_SYSBUS_POLICY_DIR = @sysbuspath@ LIBEXECBINS = sbin/sssd_nss sbin/sssd_dp sbin/sssd_be sbin/sssd_info sbin/sssd_pk DBUS_SYSBUS_POLICIES = infopipe/org.freeipa.sssd.infopipe.conf BINS = sbin/sssd $(LIBEXECBINS) -SOLIBS = lib/libsss_proxy.$(SHLIBEXT) lib/memberof.$(SHLIBEXT) +SOLIBS = lib/libsysdb.$(SHLIBEXT) lib/libsss_proxy.$(SHLIBEXT) lib/memberof.$(SHLIBEXT) +TESTS = tests/sysdb-tests DIRS = sbin lib -all: showflags dirs $(OBJS) $(BINS) $(SOLIBS) +all: showflags dirs $(OBJS) $(SOLIBS) $(BINS) shared-build: all +tests: all $(TESTS) + dirs: @mkdir -p $(DIRS) clean:: rm -f $(OBJS) $(BINS) $(MODULES) rm -f *.o */*.o */*/*.o - rm -f $(BINS) $(SOLIBS) + rm -f $(BINS) $(SOLIBS) $(TESTS) distclean:: clean rm -rf $(DIRS) @@ -100,6 +106,7 @@ install:: all installdirs installheaders installlibs installbin installsupport ${INSTALLCMD} -m 755 sbin/sssd $(DESTDIR)$(sbindir) ${INSTALLCMD} -d $(DESTDIR)$(SSSD_LIBEXEC_PATH) ${INSTALLCMD} -m 755 $(LIBEXECBINS) $(DESTDIR)$(SSSD_LIBEXEC_PATH) + ${INSTALLCMD} -m 755 lib/sysdb.$(SHLIBEXT) $(DESTDIR)$(libdir) ${INSTALLCMD} -m 755 lib/libsss_proxy.$(SHLIBEXT) $(DESTDIR)$(libdir) ${INSTALLCMD} -m 755 lib/memberof.$(SHLIBEXT) $(DESTDIR)$(libdir) diff --git a/server/configure.ac b/server/configure.ac index 54dedd9d8..fda38db2f 100644 --- a/server/configure.ac +++ b/server/configure.ac @@ -47,7 +47,8 @@ m4_include(libevents.m4) m4_include(libldb.m4) m4_include(util/signal.m4) -PKG_CHECK_MODULES(DBUS,dbus-1) +PKG_CHECK_MODULES([DBUS],[dbus-1]) +PKG_CHECK_MODULES([CHECK],[check]) AC_SUBST(TESTS) AC_SUBST(EXTRA_OBJ) diff --git a/server/db/sysdb.c b/server/db/sysdb.c index aedf7ef2c..5e94aab80 100644 --- a/server/db/sysdb.c +++ b/server/db/sysdb.c @@ -203,7 +203,7 @@ int sysdb_getpwuid(TALLOC_CTX *mem_ctx, struct event_context *ev, struct sysdb_ctx *ctx, const char *domain, - uint64_t uid, + uid_t uid, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; @@ -497,7 +497,7 @@ int sysdb_getgrgid(TALLOC_CTX *mem_ctx, struct event_context *ev, struct sysdb_ctx *ctx, const char *domain, - uint64_t gid, + gid_t gid, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; @@ -734,7 +734,7 @@ int sysdb_store_account_posix(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, const char *domain, char *name, char *pwd, - uint64_t uid, uint64_t gid, + uid_t uid, gid_t gid, char *gecos, char *homedir, char *shell) { TALLOC_CTX *tmp_ctx; @@ -1094,6 +1094,172 @@ done: talloc_free(tmp_ctx); return ret; } +int sysdb_store_group_posix(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *name, gid_t gid) +{ + TALLOC_CTX *tmp_ctx; + const char *attrs[] = { SYSDB_GR_NAME, NULL }; + struct ldb_dn *group_dn; + struct ldb_result *res; + struct ldb_request *req; + struct ldb_message *msg; + int ret, lret; + int flags; + + tmp_ctx = talloc_new(memctx); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + "gid=%s,"SYSDB_TMPL_GROUP_BASE, + name, domain); + if (group_dn == NULL) { + ret = ENOMEM; + talloc_free(tmp_ctx); + return ENOMEM; + } + + /* Start a transaction to ensure that nothing changes + * underneath us while we're working + */ + lret = ldb_transaction_start(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); + talloc_free(tmp_ctx); + return EIO; + } + + /* Determine if the group already exists */ + lret = ldb_search(sysdb->ldb, tmp_ctx, &res, group_dn, + LDB_SCOPE_BASE, attrs, SYSDB_GRENT_FILTER); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make search request: %s(%d)[%s]\b", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + req = NULL; + + switch(res->count) { + case 0: + flags = LDB_FLAG_MOD_ADD; + DEBUG(3, ("Adding new entry\n")); + break; + case 1: + flags = LDB_FLAG_MOD_REPLACE; + DEBUG(3, ("Replacing existing entry\n")); + break; + default: + DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", + res->count)); + ret = EIO; + goto done; + } + talloc_free(res); + res = NULL; + + /* Set up the add/replace request */ + msg = ldb_msg_new(tmp_ctx); + if (msg == NULL) { + ret = ENOMEM; + goto done; + } + msg->dn = group_dn; + + if (flags == LDB_FLAG_MOD_ADD) { + /* TODO: retrieve group objectclass list from configuration */ + lret = ldb_msg_add_empty(msg, "objectClass", flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, "objectClass", "group"); + } + if (lret != LDB_SUCCESS) { + ret = errno; + goto done; + } + + /* TODO: retrieve groupname attribute from configuration */ + lret = ldb_msg_add_empty(msg, SYSDB_GR_NAME, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, SYSDB_GR_NAME, name); + } + if (lret != LDB_SUCCESS) { + ret = errno; + goto done; + } + } + + /* TODO: retrieve attribute name mappings from configuration */ + /* gid */ + if (gid) { + lret = ldb_msg_add_empty(msg, SYSDB_GR_GIDNUM, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_fmt(msg, SYSDB_GR_GIDNUM, + "%lu", (unsigned long)gid); + } + if (lret != LDB_SUCCESS) { + ret = errno; + goto done; + } + } else { + DEBUG(0, ("Cached groups can't have GID == 0\n")); + ret = EINVAL; + goto done; + } + + /* modification time */ + lret = ldb_msg_add_empty(msg, SYSDB_LAST_UPDATE, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_fmt(msg, SYSDB_LAST_UPDATE, + "%ld", (long int)time(NULL)); + } + if (lret != LDB_SUCCESS) { + ret = errno; + goto done; + } + + if (flags == LDB_FLAG_MOD_ADD) { + lret = ldb_build_add_req(&req, sysdb->ldb, tmp_ctx, msg, NULL, + NULL, ldb_op_default_callback, NULL); + } else { + lret = ldb_build_mod_req(&req, sysdb->ldb, tmp_ctx, msg, NULL, + NULL, ldb_op_default_callback, NULL); + } + if (lret == LDB_SUCCESS) { + lret = ldb_request(sysdb->ldb, req); + if (lret == LDB_SUCCESS) { + lret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + } + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + lret = ldb_transaction_commit(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); + ret = EIO; + goto done; + } + + ret = EOK; + +done: + if (ret != EOK) { + lret = ldb_transaction_cancel(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); + } + } + talloc_free(tmp_ctx); + return ret; +} int sysdb_init(TALLOC_CTX *mem_ctx, struct event_context *ev, diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 5b7875961..582b8abeb 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -97,7 +97,7 @@ int sysdb_getpwuid(TALLOC_CTX *mem_ctx, struct event_context *ev, struct sysdb_ctx *ctx, const char *domain, - uint64_t uid, + uid_t uid, sysdb_callback_t fn, void *ptr); int sysdb_enumpwent(TALLOC_CTX *mem_ctx, @@ -116,7 +116,7 @@ int sysdb_getgrgid(TALLOC_CTX *mem_ctx, struct event_context *ev, struct sysdb_ctx *ctx, const char *domain, - uint64_t gid, + gid_t gid, sysdb_callback_t fn, void *ptr); int sysdb_enumgrent(TALLOC_CTX *mem_ctx, @@ -135,7 +135,7 @@ int sysdb_store_account_posix(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, const char *domain, char *name, char *pwd, - uint64_t uid, uint64_t gid, + uid_t uid, gid_t gid, char *gecos, char *homedir, char *shell); int sysdb_remove_account_posix(TALLOC_CTX *memctx, @@ -145,4 +145,9 @@ int sysdb_remove_account_posix(TALLOC_CTX *memctx, int sysdb_remove_account_posix_by_uid(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, const char *domain, uid_t uid); + +int sysdb_store_group_posix(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *name, gid_t gid); #endif /* __SYS_DB_H__ */ diff --git a/server/nss/nsssrv_cmd.c b/server/nss/nsssrv_cmd.c index ef803cf57..dd750c280 100644 --- a/server/nss/nsssrv_cmd.c +++ b/server/nss/nsssrv_cmd.c @@ -106,7 +106,7 @@ static int nss_check_domain(struct ldb_dn *dn, key = "LOCAL"; } - basedn = btreemap_get_value(domain_map, (void *)key); + basedn = btreemap_get_value(domain_map, key); if (!basedn) { DEBUG(4, ("Domain (%s) not found in map!\n", domain)); return EINVAL; diff --git a/server/server.mk b/server/server.mk index 348bbc8a7..4832f0041 100644 --- a/server/server.mk +++ b/server/server.mk @@ -10,7 +10,9 @@ UTIL_OBJ = \ sbus/sssd_dbus_connection.o \ sbus/sssd_dbus_server.o \ sbus/sbus_client.o \ - confdb/confdb.o \ + confdb/confdb.o + +SYSDB_OBJ = \ db/sysdb.o SERVER_OBJ = \ @@ -41,17 +43,20 @@ POLKIT_OBJ = \ MEMBEROF_OBJ = \ ldb_modules/memberof.o +SYSDB_TEST_OBJ = \ + tests/sysdb-tests.o + sbin/sssd: $(SERVER_OBJ) $(UTIL_OBJ) $(CC) -o sbin/sssd $(SERVER_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) sbin/sssd_nss: $(NSSSRV_OBJ) $(UTIL_OBJ) - $(CC) -o sbin/sssd_nss $(NSSSRV_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) + $(CC) -o sbin/sssd_nss $(NSSSRV_OBJ) $(UTIL_OBJ) -lsysdb $(LDFLAGS) $(LIBS) sbin/sssd_dp: $(DP_OBJ) $(UTIL_OBJ) $(CC) -o sbin/sssd_dp $(DP_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) -sbin/sssd_be: $(DP_BE_OBJ) $(UTIL_OBJ) - $(CC) -Wl,-E -o sbin/sssd_be $(DP_BE_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) +sbin/sssd_be: $(DP_BE_OBJ) $(UTIL_OBJ) + $(CC) -Wl,-E -o sbin/sssd_be $(DP_BE_OBJ) $(UTIL_OBJ) -lsysdb $(LDFLAGS) $(LIBS) sbin/sssd_info: $(INFOPIPE_OBJ) $(UTIL_OBJ) $(CC) -o sbin/sssd_info $(INFOPIPE_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) @@ -59,8 +64,15 @@ sbin/sssd_info: $(INFOPIPE_OBJ) $(UTIL_OBJ) sbin/sssd_pk: $(POLKIT_OBJ) $(UTIL_OBJ) $(CC) -o sbin/sssd_pk $(POLKIT_OBJ) $(UTIL_OBJ) $(LDFLAGS) $(LIBS) +lib/libsysdb.$(SHLIBEXT): $(SYSDB_OBJ) + $(SHLD) $(SHLD_FLAGS) -o $@ $(SYSDB_OBJ) $(LDFLAGS) $(LIBS) + lib/libsss_proxy.$(SHLIBEXT): $(PROXY_BE_OBJ) $(SHLD) $(SHLD_FLAGS) -o $@ $(PROXY_BE_OBJ) $(LDFLAGS) $(LIBS) lib/memberof.$(SHLIBEXT): $(MEMBEROF_OBJ) $(SHLD) $(SHLD_FLAGS) -o $@ $(MEMBEROF_OBJ) $(LDFLAGS) $(LDB_LIBS) + +#Tests +tests/sysdb-tests: $(SYSDB_TEST_OBJ) $(UTIL_OBJ) lib/libsysdb.$(SHLIBEXT) + $(CC) -o tests/sysdb-tests $(SYSDB_TEST_OBJ) $(UTIL_OBJ) -lsysdb $(LDFLAGS) $(LIBS) $(CHECK_LIBS) \ No newline at end of file diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c new file mode 100644 index 000000000..ef49d4152 --- /dev/null +++ b/server/tests/sysdb-tests.c @@ -0,0 +1,165 @@ +/* + SSSD + + System Database + + Copyright (C) Stephen Gallagher 2009 + + 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 . +*/ + +#include +#include +#include +#include +#include +#include "util/util.h" +#include "confdb/confdb.h" +#include "db/sysdb.h" + +struct sysdb_test_ctx { + struct sysdb_ctx *sysdb; + struct confdb_ctx *confdb; + struct event_context *ev; +}; + +static int setup_sysdb_tests(TALLOC_CTX *mem_ctx, struct sysdb_test_ctx **ctx) +{ + struct sysdb_test_ctx *test_ctx; + int ret; + + test_ctx = talloc_zero(mem_ctx, struct sysdb_test_ctx); + if (test_ctx == NULL) { + fail("Could not allocate memory for test context"); + return ENOMEM; + } + + /* Create an event context + * It will not be used except in confdb_init and sysdb_init + */ + test_ctx->ev = event_context_init(test_ctx); + if (test_ctx->ev == NULL) { + fail("Could not create event context"); + talloc_free(test_ctx); + return EIO; + } + + /* Connect to the conf db */ + ret = confdb_init(mem_ctx, test_ctx->ev, &test_ctx->confdb); + if(ret != EOK) { + fail("Could not initialize connection to the confdb"); + talloc_free(test_ctx); + return ret; + } + + ret = sysdb_init(test_ctx, test_ctx->ev, test_ctx->confdb, &test_ctx->sysdb); + if(ret != EOK) { + fail("Could not initialize connection to the sysdb"); + talloc_free(test_ctx); + return ret; + } + + *ctx = test_ctx; + return EOK; +} + +START_TEST (test_sysdb_store_group_posix) +{ + int ret; + struct sysdb_test_ctx *test_ctx; + TALLOC_CTX *mem_ctx; + + /* Setup */ + mem_ctx = talloc_new(NULL); + ret = setup_sysdb_tests(mem_ctx, &test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + ret = sysdb_store_group_posix(test_ctx, test_ctx->sysdb, + "LOCAL", "sysdbtestgroup", 67000); + fail_if(ret != EOK, "Could not store sysdbtestgroup"); + + talloc_free(mem_ctx); +} +END_TEST + +START_TEST (test_sysdb_replace_group_posix) +{ + int ret; + struct sysdb_test_ctx *test_ctx; + TALLOC_CTX *mem_ctx; + + /* Setup */ + mem_ctx = talloc_new(NULL); + ret = setup_sysdb_tests(mem_ctx, &test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + ret = sysdb_store_group_posix(test_ctx, test_ctx->sysdb, + "LOCAL", "sysdbtestgroup", 67001); + fail_if(ret != EOK, "Could not store sysdbtestgroup"); + + talloc_free(mem_ctx); +} +END_TEST + +Suite *create_sysdb_suite(void) +{ + Suite *s = suite_create("sysdb"); + + /* POSIX Group test case */ + TCase *tc_posix_gr = tcase_create("\tPOSIX Groups"); + tcase_add_test(tc_posix_gr, test_sysdb_store_group_posix); + tcase_add_test(tc_posix_gr, test_sysdb_replace_group_posix); + suite_add_tcase(s, tc_posix_gr); + + return s; +} + +int main(int argc, const char *argv[]) { + int opt; + poptContext pc; + int failure_count; + Suite *sysdb_suite; + SRunner *sr; + + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_MAIN_OPTS + { NULL } + }; + + 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); + + sysdb_suite = create_sysdb_suite(); + sr = srunner_create(sysdb_suite); + srunner_run_all(sr, CK_VERBOSE); + failure_count = srunner_ntests_failed(sr); + srunner_free(sr); + return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/server/util/debug.c b/server/util/debug.c index 6fd6ccc3d..1398f800f 100644 --- a/server/util/debug.c +++ b/server/util/debug.c @@ -4,7 +4,7 @@ #include const char *debug_prg_name = "sssd"; -int debug_level = 3; +int debug_level = 0; void debug_fn(const char *format, ...) { -- cgit