]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: flush nscd's caches whenever we allocate/release a dynamic user 11086/head
authorLennart Poettering <lennart@poettering.net>
Fri, 7 Dec 2018 16:03:32 +0000 (17:03 +0100)
committerLennart Poettering <lennart@poettering.net>
Sat, 15 Dec 2018 11:10:19 +0000 (12:10 +0100)
This should make dynamic users and nscd work together better.

Fixes: #10740
src/core/dynamic-user.c

index 889492aeece01439097c733ad0761f015ce5e045..089461a18aa53c4926d8310a184c7a9fbc87e763 100644 (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;
 }