From: Lennart Poettering Date: Fri, 7 Dec 2018 16:03:32 +0000 (+0100) Subject: core: flush nscd's caches whenever we allocate/release a dynamic user X-Git-Tag: v240~44^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F11086%2Fhead;p=thirdparty%2Fsystemd.git core: flush nscd's caches whenever we allocate/release a dynamic user This should make dynamic users and nscd work together better. Fixes: #10740 --- diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index 889492aeece..089461a18aa 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -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; }