core: flush nscd's caches whenever we allocate/release a dynamic user

This should make dynamic users and nscd work together better.

Fixes: #10740
This commit is contained in:
Lennart Poettering
2018-12-15 12:10:19 +01:00
parent 7782e0a0ea
commit 460ec54908
+13
View File
@@ -10,6 +10,7 @@
#include "fileio.h"
#include "fs-util.h"
#include "io-util.h"
#include "nscd-flush.h"
#include "parse-util.h"
#include "random-util.h"
#include "serialize.h"
@@ -383,6 +384,7 @@ static int dynamic_user_realize(
_cleanup_close_ int etc_passwd_lock_fd = -1;
uid_t num = UID_INVALID; /* a uid if is_user, and a gid otherwise */
gid_t gid = GID_INVALID; /* a gid if is_user, ignored otherwise */
bool flush_cache = false;
int r;
assert(d);
@@ -471,6 +473,7 @@ static int dynamic_user_realize(
}
/* Great! Nothing is stored here, still. Store our newly acquired data. */
flush_cache = true;
} else {
/* Hmm, so as it appears there's now something stored in the storage socket. Throw away what we
* acquired, and use what's stored now. */
@@ -500,6 +503,14 @@ static int dynamic_user_realize(
if (r < 0)
return r;
if (flush_cache) {
/* If we allocated a new dynamic UID, refresh nscd, so that it forgets about potentially cached
* negative entries. But let's do so after we release the /etc/passwd lock, so that there's no
* potential for nscd wanting to lock that for completing the invalidation. */
etc_passwd_lock_fd = safe_close(etc_passwd_lock_fd);
(void) nscd_flush_cache(STRV_MAKE("passwd", "group"));
}
if (is_user) {
*ret_uid = num;
*ret_gid = gid != GID_INVALID ? gid : num;
@@ -572,6 +583,8 @@ static int dynamic_user_close(DynamicUser *d) {
/* This dynamic user was realized and dynamically allocated. In this case, let's remove the lock file. */
unlink_uid_lock(lock_fd, uid, d->name);
(void) nscd_flush_cache(STRV_MAKE("passwd", "group"));
return 1;
}