]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/offline-passwd.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include "offline-passwd.h"
8 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(uid_gid_hash_ops
, char, string_hash_func
, string_compare_func
, free
);
10 static int open_passwd_file(const char *root
, const char *fname
, FILE **ret_file
) {
11 const char *p
= prefix_roota(root
, fname
);
15 FILE *f
= fopen(p
, "re");
19 log_debug("Reading %s entries from %s...", basename(fname
), p
);
25 static int populate_uid_cache(const char *root
, Hashmap
**ret
) {
26 _cleanup_(hashmap_freep
) Hashmap
*cache
= NULL
;
29 cache
= hashmap_new(&uid_gid_hash_ops
);
33 /* The directory list is harcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This
34 * could be made configurable, but I don't see the point right now. */
37 FOREACH_STRING(fname
, "/etc/passwd", "/usr/lib/passwd") {
38 _cleanup_fclose_
FILE *f
= NULL
;
40 r
= open_passwd_file(root
, fname
, &f
);
47 while ((r
= fgetpwent_sane(f
, &pw
)) > 0) {
48 _cleanup_free_
char *n
= NULL
;
50 n
= strdup(pw
->pw_name
);
54 r
= hashmap_put(cache
, n
, UID_TO_PTR(pw
->pw_uid
));
55 if (IN_SET(r
, 0 -EEXIST
))
63 *ret
= TAKE_PTR(cache
);
67 static int populate_gid_cache(const char *root
, Hashmap
**ret
) {
68 _cleanup_(hashmap_freep
) Hashmap
*cache
= NULL
;
71 cache
= hashmap_new(&uid_gid_hash_ops
);
76 FOREACH_STRING(fname
, "/etc/group", "/usr/lib/group") {
77 _cleanup_fclose_
FILE *f
= NULL
;
79 r
= open_passwd_file(root
, fname
, &f
);
86 while ((r
= fgetgrent_sane(f
, &gr
)) > 0) {
87 _cleanup_free_
char *n
= NULL
;
89 n
= strdup(gr
->gr_name
);
93 r
= hashmap_put(cache
, n
, GID_TO_PTR(gr
->gr_gid
));
94 if (IN_SET(r
, 0, -EEXIST
))
102 *ret
= TAKE_PTR(cache
);
106 int name_to_uid_offline(
120 r
= populate_uid_cache(root
, cache
);
125 found
= hashmap_get(*cache
, user
);
129 *ret_uid
= PTR_TO_UID(found
);
133 int name_to_gid_offline(
147 r
= populate_gid_cache(root
, cache
);
152 found
= hashmap_get(*cache
, group
);
156 *ret_gid
= PTR_TO_GID(found
);