1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "machined.h"
4 #include "nscd-flush.h"
5 #include "strv.h"
6 #include "user-util.h"
7 
8 #if ENABLE_NSCD
on_nscd_cache_flush_event(sd_event_source * s,void * userdata)9 static int on_nscd_cache_flush_event(sd_event_source *s, void *userdata) {
10         /* Let's ask glibc's nscd daemon to flush its caches. We request this for the three database machines may show
11          * up in: the hosts database (for resolvable machine names) and the user and group databases (for the user ns
12          * ranges). */
13 
14         (void) nscd_flush_cache(STRV_MAKE("passwd", "group", "hosts"));
15         return 0;
16 }
17 
manager_enqueue_nscd_cache_flush(Manager * m)18 int manager_enqueue_nscd_cache_flush(Manager *m) {
19         int r;
20 
21         assert(m);
22 
23         if (!m->nscd_cache_flush_event) {
24                 r = sd_event_add_defer(m->event, &m->nscd_cache_flush_event, on_nscd_cache_flush_event, m);
25                 if (r < 0)
26                         return log_error_errno(r, "Failed to allocate NSCD cache flush event: %m");
27 
28                 sd_event_source_set_description(m->nscd_cache_flush_event, "nscd-cache-flush");
29         }
30 
31         r = sd_event_source_set_enabled(m->nscd_cache_flush_event, SD_EVENT_ONESHOT);
32         if (r < 0) {
33                 m->nscd_cache_flush_event = sd_event_source_unref(m->nscd_cache_flush_event);
34                 return log_error_errno(r, "Failed to enable NSCD cache flush event: %m");
35         }
36 
37         return 0;
38 }
39 #endif
40 
manager_find_machine_for_uid(Manager * m,uid_t uid,Machine ** ret_machine,uid_t * ret_internal_uid)41 int manager_find_machine_for_uid(Manager *m, uid_t uid, Machine **ret_machine, uid_t *ret_internal_uid) {
42         Machine *machine;
43         int r;
44 
45         assert(m);
46         assert(uid_is_valid(uid));
47 
48         /* Finds the machine for the specified host UID and returns it along with the UID translated into the
49          * internal UID inside the machine */
50 
51         HASHMAP_FOREACH(machine, m->machines) {
52                 uid_t converted;
53 
54                 r = machine_owns_uid(machine, uid, &converted);
55                 if (r < 0)
56                         return r;
57                 if (r) {
58                         if (ret_machine)
59                                 *ret_machine = machine;
60 
61                         if (ret_internal_uid)
62                                 *ret_internal_uid = converted;
63 
64                         return true;
65                 }
66         }
67 
68         if (ret_machine)
69                 *ret_machine = NULL;
70         if (ret_internal_uid)
71                 *ret_internal_uid = UID_INVALID;
72 
73         return false;
74 }
75 
manager_find_machine_for_gid(Manager * m,gid_t gid,Machine ** ret_machine,gid_t * ret_internal_gid)76 int manager_find_machine_for_gid(Manager *m, gid_t gid, Machine **ret_machine, gid_t *ret_internal_gid) {
77         Machine *machine;
78         int r;
79 
80         assert(m);
81         assert(gid_is_valid(gid));
82 
83         HASHMAP_FOREACH(machine, m->machines) {
84                 gid_t converted;
85 
86                 r = machine_owns_gid(machine, gid, &converted);
87                 if (r < 0)
88                         return r;
89                 if (r) {
90                         if (ret_machine)
91                                 *ret_machine = machine;
92 
93                         if (ret_internal_gid)
94                                 *ret_internal_gid = converted;
95 
96                         return true;
97                 }
98         }
99 
100         if (ret_machine)
101                 *ret_machine = NULL;
102         if (ret_internal_gid)
103                 *ret_internal_gid = GID_INVALID;
104 
105         return false;
106 }
107