diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2023-03-08 13:00:40 +0100 |
---|---|---|
committer | Daan De Meyer <daan.j.demeyer@gmail.com> | 2023-03-10 11:57:43 +0100 |
commit | b4cbfa5f1b874590dc51bd81f956fe5b9569927c (patch) | |
tree | 396024caa105112eb0a2a20f529ff1f2c48a77da | |
parent | 663fd3e103a1d9b1dbc77ada9db7901f24338dab (diff) | |
download | systemd-b4cbfa5f1b874590dc51bd81f956fe5b9569927c.tar.gz |
lock-util: Add CLEANUP_UNPOSIX_UNLOCK()
Also migrate the logic in dynamic-user.c to use the new cleanup
macro.
-rw-r--r-- | src/core/dynamic-user.c | 36 | ||||
-rw-r--r-- | src/shared/lock-util.c | 10 | ||||
-rw-r--r-- | src/shared/lock-util.h | 5 |
3 files changed, 29 insertions, 22 deletions
diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index 9f4387a21b..42936bf567 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -11,6 +11,7 @@ #include "format-util.h" #include "fs-util.h" #include "io-util.h" +#include "lock-util.h" #include "nscd-flush.h" #include "parse-util.h" #include "random-util.h" @@ -362,27 +363,12 @@ static void unlink_uid_lock(int lock_fd, uid_t uid, const char *name) { (void) make_uid_symlinks(uid, name, false); /* remove direct lookup symlinks */ } -static int lockfp(int fd, int *fd_lock) { - if (lockf(fd, F_LOCK, 0) < 0) - return -errno; - *fd_lock = fd; - return 0; -} - -static void unlockfp(int *fd_lock) { - if (*fd_lock < 0) - return; - lockf(*fd_lock, F_ULOCK, 0); - *fd_lock = -EBADF; -} - static int dynamic_user_realize( DynamicUser *d, char **suggested_dirs, uid_t *ret_uid, gid_t *ret_gid, bool is_user) { - _cleanup_(unlockfp) int storage_socket0_lock = -EBADF; _cleanup_close_ int uid_lock_fd = -EBADF; _cleanup_close_ int etc_passwd_lock_fd = -EBADF; uid_t num = UID_INVALID; /* a uid if is_user, and a gid otherwise */ @@ -397,10 +383,12 @@ static int dynamic_user_realize( /* Acquire a UID for the user name. This will allocate a UID for the user name if the user doesn't exist * yet. If it already exists its existing UID/GID will be reused. */ - r = lockfp(d->storage_socket[0], &storage_socket0_lock); + r = unposix_lock(d->storage_socket[0], LOCK_EX); if (r < 0) return r; + CLEANUP_UNPOSIX_UNLOCK(d->storage_socket[0]); + r = dynamic_user_pop(d, &num, &uid_lock_fd); if (r < 0) { int new_uid_lock_fd; @@ -411,7 +399,9 @@ static int dynamic_user_realize( /* OK, nothing stored yet, let's try to find something useful. While we are working on this release the * lock however, so that nobody else blocks on our NSS lookups. */ - unlockfp(&storage_socket0_lock); + r = unposix_lock(d->storage_socket[0], LOCK_UN); + if (r < 0) + return r; /* Let's see if a proper, static user or group by this name exists. Try to take the lock on * /etc/passwd, if that fails with EROFS then /etc is read-only. In that case it's fine if we don't @@ -461,7 +451,7 @@ static int dynamic_user_realize( } /* So, we found a working UID/lock combination. Let's see if we actually still need it. */ - r = lockfp(d->storage_socket[0], &storage_socket0_lock); + r = unposix_lock(d->storage_socket[0], LOCK_EX); if (r < 0) { unlink_uid_lock(uid_lock_fd, num, d->name); return r; @@ -524,7 +514,6 @@ static int dynamic_user_realize( } int dynamic_user_current(DynamicUser *d, uid_t *ret) { - _cleanup_(unlockfp) int storage_socket0_lock = -EBADF; _cleanup_close_ int lock_fd = -EBADF; uid_t uid; int r; @@ -534,10 +523,12 @@ int dynamic_user_current(DynamicUser *d, uid_t *ret) { /* Get the currently assigned UID for the user, if there's any. This simply pops the data from the * storage socket, and pushes it back in right-away. */ - r = lockfp(d->storage_socket[0], &storage_socket0_lock); + r = unposix_lock(d->storage_socket[0], LOCK_EX); if (r < 0) return r; + CLEANUP_UNPOSIX_UNLOCK(d->storage_socket[0]); + r = dynamic_user_pop(d, &uid, &lock_fd); if (r < 0) return r; @@ -567,7 +558,6 @@ static DynamicUser* dynamic_user_unref(DynamicUser *d) { } static int dynamic_user_close(DynamicUser *d) { - _cleanup_(unlockfp) int storage_socket0_lock = -EBADF; _cleanup_close_ int lock_fd = -EBADF; uid_t uid; int r; @@ -575,10 +565,12 @@ static int dynamic_user_close(DynamicUser *d) { /* Release the user ID, by releasing the lock on it, and emptying the storage socket. After this the * user is unrealized again, much like it was after it the DynamicUser object was first allocated. */ - r = lockfp(d->storage_socket[0], &storage_socket0_lock); + r = unposix_lock(d->storage_socket[0], LOCK_EX); if (r < 0) return r; + CLEANUP_UNPOSIX_UNLOCK(d->storage_socket[0]); + r = dynamic_user_pop(d, &uid, &lock_fd); if (r == -EAGAIN) /* User wasn't realized yet, nothing to do. */ diff --git a/src/shared/lock-util.c b/src/shared/lock-util.c index bbbd314643..2d8ed1a2b3 100644 --- a/src/shared/lock-util.c +++ b/src/shared/lock-util.c @@ -149,3 +149,13 @@ int unposix_lock(int fd, int operation) { return r; } + +void unposix_unlockpp(int **fd) { + assert(fd); + + if (!*fd || **fd < 0) + return; + + (void) unposix_lock(**fd, LOCK_UN); + *fd = NULL; +} diff --git a/src/shared/lock-util.h b/src/shared/lock-util.h index 66f8635133..e8d4c24874 100644 --- a/src/shared/lock-util.h +++ b/src/shared/lock-util.h @@ -15,3 +15,8 @@ void release_lock_file(LockFile *f); /* Open File Description locks with the same interface as flock(). */ int unposix_lock(int fd, int operation); + +void unposix_unlockpp(int **fd); + +#define CLEANUP_UNPOSIX_UNLOCK(fd) \ + _cleanup_(unposix_unlockpp) _unused_ int *CONCATENATE(_cleanup_unposix_unlock_, UNIQ) = &(fd) |