diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/conf_macros.m4 | 14 | ||||
-rw-r--r-- | src/monitor/monitor.c | 32 | ||||
-rw-r--r-- | src/util/nscd.c | 129 | ||||
-rw-r--r-- | src/util/util.h | 2 |
6 files changed, 177 insertions, 7 deletions
diff --git a/Makefile.am b/Makefile.am index c6680521..cfac3061 100644 --- a/Makefile.am +++ b/Makefile.am @@ -617,7 +617,8 @@ include_HEADERS = \ sssd_SOURCES = \ src/monitor/monitor.c \ src/monitor/monitor_netlink.c \ - src/confdb/confdb_setup.c + src/confdb/confdb_setup.c \ + src/util/nscd.c sssd_LDADD = \ $(SSSD_LIBS) \ $(LIBNL_LIBS) \ diff --git a/configure.ac b/configure.ac index f90d7fee..e63e6787 100644 --- a/configure.ac +++ b/configure.ac @@ -166,6 +166,10 @@ fi WITH_LIBNL +if test x$HAVE_NSCD; then + WITH_NSCD_CONF +fi + WITH_INITSCRIPT if test x$initscript = xsystemd; then WITH_SYSTEMD_UNIT_DIR diff --git a/src/conf_macros.m4 b/src/conf_macros.m4 index 26eb4acc..c72b3dd7 100644 --- a/src/conf_macros.m4 +++ b/src/conf_macros.m4 @@ -352,6 +352,20 @@ AC_DEFUN([WITH_NSCD], AC_DEFINE_UNQUOTED(HAVE_NSCD, $NSCD_PATH, [flush nscd cache after local domain operations]) ]) +AC_DEFUN([WITH_NSCD_CONF], + [ AC_ARG_WITH([nscd_conf], + [AC_HELP_STRING([--with-nscd-conf=PATH], [Path to nscd.conf file [/etc/nscd.conf]]) + ] + ) + + NSCD_CONF_PATH="/etc/nscd.conf" + if test x"$with_nscd_conf" != x; then + NSCD_CONF_PATH=$with_nscd_conf + fi + AC_DEFINE_UNQUOTED([NSCD_CONF_PATH], ["$NSCD_CONF_PATH"], [NSCD configuration file]) + ]) + + AC_DEFUN([WITH_SEMANAGE], [ AC_ARG_WITH([semanage], [AC_HELP_STRING([--with-semanage], diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index bd22a951..8882e4db 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -2754,12 +2754,32 @@ int main(int argc, const char *argv[]) /* Warn if nscd seems to be running */ ret = check_file(NSCD_SOCKET_PATH, -1, -1, -1, CHECK_SOCK, NULL, false); if (ret == EOK) { - sss_log(SSS_LOG_NOTICE, - "nscd socket was detected. Nscd caching capabilities " - "may conflict with SSSD for users and groups. It is " - "recommended not to run nscd in parallel with SSSD, unless " - "nscd is configured not to cache the passwd, group and " - "netgroup nsswitch maps."); + ret = sss_nscd_parse_conf(NSCD_CONF_PATH); + + switch (ret) { + case ENOENT: + sss_log(SSS_LOG_NOTICE, + "NSCD socket was detected. NSCD caching capabilities " + "may conflict with SSSD for users and groups. It is " + "recommended not to run NSCD in parallel with SSSD, " + "unless NSCD is configured not to cache the passwd, " + "group, netgroup and services nsswitch maps."); + break; + + case EEXIST: + sss_log(SSS_LOG_NOTICE, + "NSCD socket was detected and seems to be configured " + "to cache some of the databases controlled by " + "SSSD [passwd,group,netgroup,services]. It is " + "recommended not to run NSCD in parallel with SSSD, " + "unless NSCD is configured not to cache these."); + break; + + case EOK: + DEBUG(SSSDBG_TRACE_FUNC, ("NSCD socket was detected and it " + "seems to be configured not to interfere with " + "SSSD's caching capabilities\n")); + } } /* Parse config file, fail if cannot be done */ diff --git a/src/util/nscd.c b/src/util/nscd.c index b9f2ba88..2a06394d 100644 --- a/src/util/nscd.c +++ b/src/util/nscd.c @@ -95,3 +95,132 @@ int flush_nscd_cache(enum nscd_db flush_db) return EOK; } #endif + +/* NSCD config file parse and check */ + +static unsigned int sss_nscd_check_service(char* svc_name) +{ + struct sss_nscd_db { + const char *svc_type_name; + unsigned int nscd_service_flag; + }; + + int i; + unsigned int ret = 0; + struct sss_nscd_db db[] = { + { "passwd", 0x0001 }, + { "group", 0x0010 }, + { "netgroup", 0x0100 }, + { "services", 0x1000 }, + { NULL, 0 } + }; + + if (svc_name == NULL) { + return ret; + } + + for (i = 0; db[i].svc_type_name != NULL; i++) { + if (!strcmp(db[i].svc_type_name, svc_name)) { + + ret = db[i].nscd_service_flag; + break; + } + } + + return ret; +} + +errno_t sss_nscd_parse_conf(const char *conf_path) +{ + FILE *fp; + int ret = EOK; + unsigned int occured = 0; + char *line, *entry, *service, *enabled, *pad; + size_t linelen = 0; + + fp = fopen(conf_path, "r"); + if (fp == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, ("Couldn't open NSCD configuration " + "file [%s]\n", NSCD_CONF_PATH)); + return ENOENT; + } + + while (getline(&line, &linelen, fp) != -1) { + + entry = NULL; + service = NULL; + enabled = NULL; + + pad = strchr(line, '#'); + if (pad != NULL) { + *pad = '\0'; + } + + if (line[0] == '\n' || line[0] == '\0') continue; + + entry = line; + while (isspace(*entry) && *entry != '\0') { + entry++; + } + + pad = entry; + while (!isspace(*pad) && *pad != '\0') { + pad++; + } + + service = pad; + while (isspace(*service) && *service != '\0') { + service++; + } + + *pad = '\0'; + pad = service; + while (!isspace(*pad) && *pad != '\0') { + pad++; + } + + enabled = pad; + while (isspace(*enabled) && *enabled != '\0') { + enabled++; + } + + *pad = '\0'; + pad = enabled; + while (!isspace(*pad) && *pad != '\0') { + pad++; + } + *pad = '\0'; + + if (entry != NULL && + service != NULL && + enabled != NULL) { + + if (!strcmp(entry, "enable-cache") && + !strcmp(enabled, "yes")) { + + occured |= sss_nscd_check_service(service); + } + } + }; + + ret = ferror(fp); + if (ret) { + DEBUG(SSSDBG_MINOR_FAILURE, ("Reading NSCD configuration file [%s] " + "ended with failure [%d]: %s.\n", + NSCD_CONF_PATH, ret, strerror(ret))); + ret = ENOENT; + goto done; + } + + ret = EOK; + if (occured != 0) { + ret = EEXIST; + goto done; + } + +done: + free(line); + fclose(fp); + + return ret; +} diff --git a/src/util/util.h b/src/util/util.h index 56653038..bdb04a8f 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -499,6 +499,8 @@ enum nscd_db { int flush_nscd_cache(enum nscd_db flush_db); +errno_t sss_nscd_parse_conf(const char *conf_path); + /* from sss_tc_utf8.c */ char * sss_tc_utf8_str_tolower(TALLOC_CTX *mem_ctx, const char *s); |