diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2013-07-26 14:26:55 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2013-07-26 14:26:55 +0200 |
commit | 6054499f9a9952593ccadc83182e01d39ff62f12 (patch) | |
tree | 74b61921f9bcbf780863060971a2bf280a9fd5c3 | |
parent | d2e2e400e79c94c2e60f21ec61811dfe948924cc (diff) |
Allow invalidating the nfsidmap cache
This introduces an nfsidmap value for nscd_invalidate which will cause
the nfsidmap -c command to be run.
-rw-r--r-- | man/nslcd.conf.5.xml | 16 | ||||
-rw-r--r-- | nslcd/attmap.c | 3 | ||||
-rw-r--r-- | nslcd/cfg.c | 1 | ||||
-rw-r--r-- | nslcd/cfg.h | 1 | ||||
-rw-r--r-- | nslcd/nscd.c | 24 | ||||
-rw-r--r-- | pynslcd/cfg.py | 2 | ||||
-rw-r--r-- | pynslcd/nscd.py | 32 |
7 files changed, 54 insertions, 25 deletions
diff --git a/man/nslcd.conf.5.xml b/man/nslcd.conf.5.xml index 87d21f8..9435e3a 100644 --- a/man/nslcd.conf.5.xml +++ b/man/nslcd.conf.5.xml @@ -825,13 +825,21 @@ <para> If this option is set, on start-up and whenever a connection to the <acronym>LDAP</acronym> server is re-established after an error + the specified cache is flushed. + </para> + <para> + If <replaceable>DB</replaceable> is one of the nsswitch maps, <command>nscd</command> is contacted to flush it's cache for the - configured databases. + specified database. + </para> + <para> <!-- since 0.9.1 --> + If <replaceable>DB</replaceable> is <literal>nfsidmap</literal>, + <command>nfsidmap</command> to contacted to clear it's cache. </para> <para> - Using this option ensures that <command>nscd</command> is not - caching absence of users that were not available if the LDAP server - was unavailable. + Using this option ensures that external caches are cleared of + information (typically the absence of users) while the + <acronym>LDAP</acronym> server was unavailable. </para> </listitem> </varlistentry> diff --git a/nslcd/attmap.c b/nslcd/attmap.c index 2480096..08130fa 100644 --- a/nslcd/attmap.c +++ b/nslcd/attmap.c @@ -57,6 +57,7 @@ const char **base_get_var(enum ldap_map_selector map) case LM_RPC: return rpc_bases; case LM_SERVICES: return service_bases; case LM_SHADOW: return shadow_bases; + case LM_NFSIDMAP: case LM_NONE: default: return NULL; } @@ -90,6 +91,7 @@ int *scope_get_var(enum ldap_map_selector map) case LM_RPC: return &rpc_scope; case LM_SERVICES: return &service_scope; case LM_SHADOW: return &shadow_scope; + case LM_NFSIDMAP: case LM_NONE: default: return NULL; } @@ -123,6 +125,7 @@ const char **filter_get_var(enum ldap_map_selector map) case LM_RPC: return &rpc_filter; case LM_SERVICES: return &service_filter; case LM_SHADOW: return &shadow_filter; + case LM_NFSIDMAP: case LM_NONE: default: return NULL; } diff --git a/nslcd/cfg.c b/nslcd/cfg.c index 056b6e2..381ddec 100644 --- a/nslcd/cfg.c +++ b/nslcd/cfg.c @@ -527,6 +527,7 @@ static const char *print_map(enum ldap_map_selector map) case LM_RPC: return "rpc"; case LM_SERVICES: return "services"; case LM_SHADOW: return "shadow"; + case LM_NFSIDMAP: return "nfsidmap"; case LM_NONE: default: return "???"; } diff --git a/nslcd/cfg.h b/nslcd/cfg.h index bd53560..4ec31ff 100644 --- a/nslcd/cfg.h +++ b/nslcd/cfg.h @@ -67,6 +67,7 @@ enum ldap_map_selector { LM_RPC, LM_SERVICES, LM_SHADOW, + LM_NFSIDMAP, /* only used for cache invalidation */ LM_NONE }; diff --git a/nslcd/nscd.c b/nslcd/nscd.c index da58c2e..14a976c 100644 --- a/nslcd/nscd.c +++ b/nslcd/nscd.c @@ -55,6 +55,7 @@ static const char *map2name(enum ldap_map_selector map) case LM_RPC: return "rpc"; case LM_SERVICES: return "services"; case LM_SHADOW: return "shadow"; + case LM_NFSIDMAP: return "nfsidmap"; case LM_NONE: default: return NULL; } @@ -65,7 +66,7 @@ static void exec_invalidate(const char *db) { pid_t cpid; int i, status; - char *argv[] = { "nscd", "-i", NULL, NULL }; + char *argv[4]; #ifdef HAVE_EXECVPE char *newenviron[] = { NULL }; #endif @@ -82,12 +83,25 @@ static void exec_invalidate(const char *db) i = 32; for (; i >= 0; i--) close(i); + /* build command line */ + if (strcmp(db, "nfsidmap") == 0) + { + argv[0] = "nfsidmap"; + argv[1] = "-c"; + argv[2] = NULL; + } + else + { + argv[0] = "nscd"; + argv[1] = "-i"; + argv[2] = (char *)db; + argv[3] = NULL; + } /* execute command */ - argv[2] = (char *)db; #ifdef HAVE_EXECVPE - execvpe("nscd", argv, newenviron); + execvpe(argv[0], argv, newenviron); #else - execvp("nscd", argv); + execvp(argv[0], argv); #endif /* if we are here there has been an error */ /* we can't log since we don't have any useful file descriptors */ @@ -137,7 +151,7 @@ static void nscd_handle_requests(int fd) const char *db; log_log(LOG_DEBUG, "nscd_invalidator: starting"); /* set up environment */ - chdir("/"); + (void)chdir("/"); putenv("PATH=/usr/sbin:/usr/bin:/sbin:/bin"); /* handle incoming requests */ while (1) diff --git a/pynslcd/cfg.py b/pynslcd/cfg.py index a9f1d89..516eeb7 100644 --- a/pynslcd/cfg.py +++ b/pynslcd/cfg.py @@ -317,7 +317,7 @@ def read(filename): if m: dbs = re.split('[ ,]+', m.group('value').lower()) for db in dbs: - if db not in maps: + if db not in maps.keys() + ['nfsidmap']: raise ParseError(filename, lineno, 'map %s unknown' % db) nscd_invalidate.update(dbs) continue diff --git a/pynslcd/nscd.py b/pynslcd/nscd.py index acee9a9..1cc05cf 100644 --- a/pynslcd/nscd.py +++ b/pynslcd/nscd.py @@ -34,31 +34,31 @@ signalfd = None _db_to_char = dict( aliases='A', ethers='E', group='G', hosts='H', netgroup='U', networks='N', passwd='P', protocols='L', rpc='R', services='V', - shadow='S', + shadow='S', nfsidmap='F', ) _char_to_db = dict((reversed(item) for item in _db_to_char.items())) -def exec_invalidate(db): - logging.debug('nscd_invalidator: nscd -i %s', db) +def exec_invalidate(*args): + cmd = ' '.join(args) + logging.debug('nscd_invalidator: %s', cmd) try: - p = subprocess.Popen(['nscd', '-i', db], - bufsize=4096, close_fds=True, + p = subprocess.Popen(args, bufsize=4096, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output, ignored = p.communicate() if output: output = ': %s' % output[:1024].strip() if p.returncode == 0: - logging.debug('nscd_invalidator: nscd -i %s (pid %d) success%s', - db, p.pid, output) + logging.debug('nscd_invalidator: %s (pid %d) success%s', + cmd, p.pid, output) elif p.returncode > 0: - logging.debug('nscd_invalidator: nscd -i %s (pid %d) failed (%d)%s', - db, p.pid, p.returncode, output) + logging.debug('nscd_invalidator: %s (pid %d) failed (%d)%s', + cmd, p.pid, p.returncode, output) else: # p.returncode < 0 - logging.error('nscd_invalidator: nscd -i %s (pid %d) killed by signal %d%s', - db, p.pid, -p.returncode, output) + logging.error('nscd_invalidator: %s (pid %d) killed by signal %d%s', + cmd, p.pid, -p.returncode, output) except: - logging.warn('nscd_invalidator: nscd -i %s failed', db, exc_info=True) + logging.warn('nscd_invalidator: %s failed', cmd, exc_info=True) def loop(fd): @@ -76,8 +76,10 @@ def loop(fd): if db == '': break # close process down db = _char_to_db.get(db, None) - if db: - exec_invalidate(db) + if db == 'nfsidmap': + exec_invalidate('nfsidmap', '-c') + else if db: + exec_invalidate('nscd', '-i', db) def start_invalidator(): @@ -107,4 +109,4 @@ def invalidate(db=None): try: os.write(signalfd, db) except: - logging.warn('nscd_invalidator: nscd -i %s failed', db, exc_info=True) + logging.warn('requesting invalidation (%s) failed', db, exc_info=True) |