]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/offline-passwd.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "offline-passwd.h"
9 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(uid_gid_hash_ops
, char, string_hash_func
, string_compare_func
, free
);
11 static int open_passwd_file(const char *root
, const char *fname
, FILE **ret_file
) {
12 _cleanup_free_
char *p
= NULL
;
13 _cleanup_close_
int fd
= -1;
15 fd
= chase_symlinks_and_open(fname
, root
, CHASE_PREFIX_ROOT
, O_RDONLY
|O_CLOEXEC
, &p
);
19 FILE *f
= fdopen(fd
, "r");
25 log_debug("Reading %s entries from %s...", basename(fname
), p
);
31 static int populate_uid_cache(const char *root
, Hashmap
**ret
) {
32 _cleanup_(hashmap_freep
) Hashmap
*cache
= NULL
;
35 cache
= hashmap_new(&uid_gid_hash_ops
);
39 /* The directory list is harcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This
40 * could be made configurable, but I don't see the point right now. */
43 FOREACH_STRING(fname
, "/etc/passwd", "/usr/lib/passwd") {
44 _cleanup_fclose_
FILE *f
= NULL
;
46 r
= open_passwd_file(root
, fname
, &f
);
53 while ((r
= fgetpwent_sane(f
, &pw
)) > 0) {
54 _cleanup_free_
char *n
= NULL
;
56 n
= strdup(pw
->pw_name
);
60 r
= hashmap_put(cache
, n
, UID_TO_PTR(pw
->pw_uid
));
61 if (IN_SET(r
, 0 -EEXIST
))
69 *ret
= TAKE_PTR(cache
);
73 static int populate_gid_cache(const char *root
, Hashmap
**ret
) {
74 _cleanup_(hashmap_freep
) Hashmap
*cache
= NULL
;
77 cache
= hashmap_new(&uid_gid_hash_ops
);
82 FOREACH_STRING(fname
, "/etc/group", "/usr/lib/group") {
83 _cleanup_fclose_
FILE *f
= NULL
;
85 r
= open_passwd_file(root
, fname
, &f
);
92 while ((r
= fgetgrent_sane(f
, &gr
)) > 0) {
93 _cleanup_free_
char *n
= NULL
;
95 n
= strdup(gr
->gr_name
);
99 r
= hashmap_put(cache
, n
, GID_TO_PTR(gr
->gr_gid
));
100 if (IN_SET(r
, 0, -EEXIST
))
108 *ret
= TAKE_PTR(cache
);
112 int name_to_uid_offline(
126 r
= populate_uid_cache(root
, cache
);
131 found
= hashmap_get(*cache
, user
);
135 *ret_uid
= PTR_TO_UID(found
);
139 int name_to_gid_offline(
153 r
= populate_gid_cache(root
, cache
);
158 found
= hashmap_get(*cache
, group
);
162 *ret_gid
= PTR_TO_GID(found
);