diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2020-04-11 16:08:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-11 16:08:33 +0200 |
commit | 2d9123cebddfee7cff3052061517c495c5e359cd (patch) | |
tree | c2af1810cd0baf0ce801e4e26aba63eb2a0649af | |
parent | Merge pull request #15392 from keszybz/flag-helper (diff) | |
parent | logind: avoid shadow lookups when doing userdb client side (diff) | |
download | systemd-2d9123cebddfee7cff3052061517c495c5e359cd.tar.xz systemd-2d9123cebddfee7cff3052061517c495c5e359cd.zip |
Merge pull request #15377 from poettering/userdb-no-shadow
don't try to access shadow from logind
-rw-r--r-- | src/home/pam_systemd_home.c | 1 | ||||
-rw-r--r-- | src/login/logind-core.c | 4 | ||||
-rw-r--r-- | src/nss-systemd/nss-systemd.c | 2 | ||||
-rw-r--r-- | src/nss-systemd/userdb-glue.c | 4 | ||||
-rw-r--r-- | src/shared/group-record-nss.c | 52 | ||||
-rw-r--r-- | src/shared/group-record-nss.h | 4 | ||||
-rw-r--r-- | src/shared/user-record-nss.c | 48 | ||||
-rw-r--r-- | src/shared/user-record-nss.h | 4 | ||||
-rw-r--r-- | src/shared/userdb.c | 10 | ||||
-rw-r--r-- | src/shared/userdb.h | 7 | ||||
-rw-r--r-- | src/userdb/userwork.c | 10 |
11 files changed, 89 insertions, 57 deletions
diff --git a/src/home/pam_systemd_home.c b/src/home/pam_systemd_home.c index afc72412d4..9adfd1a734 100644 --- a/src/home/pam_systemd_home.c +++ b/src/home/pam_systemd_home.c @@ -877,7 +877,6 @@ _public_ PAM_EXTERN int pam_sm_chauthtok( if (FLAGS_SET(flags, PAM_PRELIM_CHECK)) return PAM_SUCCESS; - old_secret = user_record_new(); if (!old_secret) return pam_log_oom(handle); diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 22a42b077c..a9006d746a 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -171,7 +171,7 @@ int manager_add_user_by_name( assert(m); assert(name); - r = userdb_by_name(name, 0, &ur); + r = userdb_by_name(name, USERDB_AVOID_SHADOW, &ur); if (r < 0) return r; @@ -189,7 +189,7 @@ int manager_add_user_by_uid( assert(m); assert(uid_is_valid(uid)); - r = userdb_by_uid(uid, 0, &ur); + r = userdb_by_uid(uid, USERDB_AVOID_SHADOW, &ur); if (r < 0) return r; diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c index c1e780edcb..4d63d8a2f0 100644 --- a/src/nss-systemd/nss-systemd.c +++ b/src/nss-systemd/nss-systemd.c @@ -482,7 +482,7 @@ enum nss_status _nss_systemd_getgrent_r( } } - r = nss_group_record_by_name(group_name, &gr); + r = nss_group_record_by_name(group_name, false, &gr); if (r == -ESRCH) continue; if (r < 0) { diff --git a/src/nss-systemd/userdb-glue.c b/src/nss-systemd/userdb-glue.c index 58915c3d23..a88b0d7502 100644 --- a/src/nss-systemd/userdb-glue.c +++ b/src/nss-systemd/userdb-glue.c @@ -251,7 +251,7 @@ enum nss_status userdb_getgrnam( if (lock_fd < 0 && lock_fd != -EBUSY) return lock_fd; - r = nss_group_record_by_name(name, &g); + r = nss_group_record_by_name(name, false, &g); if (r == -ESRCH) return NSS_STATUS_NOTFOUND; if (r < 0) { @@ -310,7 +310,7 @@ enum nss_status userdb_getgrgid( if (lock_fd < 0 && lock_fd != -EBUSY) return lock_fd; - r = nss_group_record_by_gid(gid, &g); + r = nss_group_record_by_gid(gid, false, &g); if (r == -ESRCH) return NSS_STATUS_NOTFOUND; diff --git a/src/shared/group-record-nss.c b/src/shared/group-record-nss.c index 77924f1c40..5c4fae865a 100644 --- a/src/shared/group-record-nss.c +++ b/src/shared/group-record-nss.c @@ -106,12 +106,16 @@ int nss_sgrp_for_group(const struct group *grp, struct sgrp *ret_sgrp, char **re } } -int nss_group_record_by_name(const char *name, GroupRecord **ret) { +int nss_group_record_by_name( + const char *name, + bool with_shadow, + GroupRecord **ret) { + _cleanup_free_ char *buf = NULL, *sbuf = NULL; struct group grp, *result; bool incomplete = false; size_t buflen = 4096; - struct sgrp sgrp; + struct sgrp sgrp, *sresult = NULL; int r; assert(name); @@ -141,13 +145,17 @@ int nss_group_record_by_name(const char *name, GroupRecord **ret) { buf = mfree(buf); } - r = nss_sgrp_for_group(result, &sgrp, &sbuf); - if (r < 0) { - log_debug_errno(r, "Failed to do shadow lookup for group %s, ignoring: %m", result->gr_name); - incomplete = ERRNO_IS_PRIVILEGE(r); - } - - r = nss_group_to_group_record(result, r >= 0 ? &sgrp : NULL, ret); + if (with_shadow) { + r = nss_sgrp_for_group(result, &sgrp, &sbuf); + if (r < 0) { + log_debug_errno(r, "Failed to do shadow lookup for group %s, ignoring: %m", result->gr_name); + incomplete = ERRNO_IS_PRIVILEGE(r); + } else + sresult = &sgrp; + } else + incomplete = true; + + r = nss_group_to_group_record(result, sresult, ret); if (r < 0) return r; @@ -155,12 +163,16 @@ int nss_group_record_by_name(const char *name, GroupRecord **ret) { return 0; } -int nss_group_record_by_gid(gid_t gid, GroupRecord **ret) { +int nss_group_record_by_gid( + gid_t gid, + bool with_shadow, + GroupRecord **ret) { + _cleanup_free_ char *buf = NULL, *sbuf = NULL; struct group grp, *result; bool incomplete = false; size_t buflen = 4096; - struct sgrp sgrp; + struct sgrp sgrp, *sresult = NULL; int r; assert(ret); @@ -188,13 +200,17 @@ int nss_group_record_by_gid(gid_t gid, GroupRecord **ret) { buf = mfree(buf); } - r = nss_sgrp_for_group(result, &sgrp, &sbuf); - if (r < 0) { - log_debug_errno(r, "Failed to do shadow lookup for group %s, ignoring: %m", result->gr_name); - incomplete = ERRNO_IS_PRIVILEGE(r); - } - - r = nss_group_to_group_record(result, r >= 0 ? &sgrp : NULL, ret); + if (with_shadow) { + r = nss_sgrp_for_group(result, &sgrp, &sbuf); + if (r < 0) { + log_debug_errno(r, "Failed to do shadow lookup for group %s, ignoring: %m", result->gr_name); + incomplete = ERRNO_IS_PRIVILEGE(r); + } else + sresult = &sgrp; + } else + incomplete = true; + + r = nss_group_to_group_record(result, sresult, ret); if (r < 0) return r; diff --git a/src/shared/group-record-nss.h b/src/shared/group-record-nss.h index 38b2995178..077c22d89f 100644 --- a/src/shared/group-record-nss.h +++ b/src/shared/group-record-nss.h @@ -11,5 +11,5 @@ int nss_group_to_group_record(const struct group *grp, const struct sgrp *sgrp, GroupRecord **ret); int nss_sgrp_for_group(const struct group *grp, struct sgrp *ret_sgrp, char **ret_buffer); -int nss_group_record_by_name(const char *name, GroupRecord **ret); -int nss_group_record_by_gid(gid_t gid, GroupRecord **ret); +int nss_group_record_by_name(const char *name, bool with_shadow, GroupRecord **ret); +int nss_group_record_by_gid(gid_t gid, bool with_shadow, GroupRecord **ret); diff --git a/src/shared/user-record-nss.c b/src/shared/user-record-nss.c index 0ff6d17117..f265a2af93 100644 --- a/src/shared/user-record-nss.c +++ b/src/shared/user-record-nss.c @@ -161,12 +161,16 @@ int nss_spwd_for_passwd(const struct passwd *pwd, struct spwd *ret_spwd, char ** } } -int nss_user_record_by_name(const char *name, UserRecord **ret) { +int nss_user_record_by_name( + const char *name, + bool with_shadow, + UserRecord **ret) { + _cleanup_free_ char *buf = NULL, *sbuf = NULL; struct passwd pwd, *result; bool incomplete = false; size_t buflen = 4096; - struct spwd spwd; + struct spwd spwd, *sresult = NULL; int r; assert(name); @@ -197,13 +201,17 @@ int nss_user_record_by_name(const char *name, UserRecord **ret) { buf = mfree(buf); } - r = nss_spwd_for_passwd(result, &spwd, &sbuf); - if (r < 0) { - log_debug_errno(r, "Failed to do shadow lookup for user %s, ignoring: %m", name); - incomplete = ERRNO_IS_PRIVILEGE(r); - } + if (with_shadow) { + r = nss_spwd_for_passwd(result, &spwd, &sbuf); + if (r < 0) { + log_debug_errno(r, "Failed to do shadow lookup for user %s, ignoring: %m", name); + incomplete = ERRNO_IS_PRIVILEGE(r); + } else + sresult = &spwd; + } else + incomplete = true; - r = nss_passwd_to_user_record(result, r >= 0 ? &spwd : NULL, ret); + r = nss_passwd_to_user_record(result, sresult, ret); if (r < 0) return r; @@ -211,12 +219,16 @@ int nss_user_record_by_name(const char *name, UserRecord **ret) { return 0; } -int nss_user_record_by_uid(uid_t uid, UserRecord **ret) { +int nss_user_record_by_uid( + uid_t uid, + bool with_shadow, + UserRecord **ret) { + _cleanup_free_ char *buf = NULL, *sbuf = NULL; struct passwd pwd, *result; bool incomplete = false; size_t buflen = 4096; - struct spwd spwd; + struct spwd spwd, *sresult = NULL; int r; assert(ret); @@ -245,13 +257,17 @@ int nss_user_record_by_uid(uid_t uid, UserRecord **ret) { buf = mfree(buf); } - r = nss_spwd_for_passwd(result, &spwd, &sbuf); - if (r < 0) { - log_debug_errno(r, "Failed to do shadow lookup for UID " UID_FMT ", ignoring: %m", uid); - incomplete = ERRNO_IS_PRIVILEGE(r); - } + if (with_shadow) { + r = nss_spwd_for_passwd(result, &spwd, &sbuf); + if (r < 0) { + log_debug_errno(r, "Failed to do shadow lookup for UID " UID_FMT ", ignoring: %m", uid); + incomplete = ERRNO_IS_PRIVILEGE(r); + } else + sresult = &spwd; + } else + incomplete = true; - r = nss_passwd_to_user_record(result, r >= 0 ? &spwd : NULL, ret); + r = nss_passwd_to_user_record(result, sresult, ret); if (r < 0) return r; diff --git a/src/shared/user-record-nss.h b/src/shared/user-record-nss.h index d5fb23ad2a..0eb78d5b52 100644 --- a/src/shared/user-record-nss.h +++ b/src/shared/user-record-nss.h @@ -11,5 +11,5 @@ int nss_passwd_to_user_record(const struct passwd *pwd, const struct spwd *spwd, UserRecord **ret); int nss_spwd_for_passwd(const struct passwd *pwd, struct spwd *ret_spwd, char **ret_buffer); -int nss_user_record_by_name(const char *name, UserRecord **ret); -int nss_user_record_by_uid(uid_t uid, UserRecord **ret); +int nss_user_record_by_name(const char *name, bool with_shadow, UserRecord **ret); +int nss_user_record_by_uid(uid_t uid, bool with_shadow, UserRecord **ret); diff --git a/src/shared/userdb.c b/src/shared/userdb.c index 0769a792c2..c3a6e02e5a 100644 --- a/src/shared/userdb.c +++ b/src/shared/userdb.c @@ -614,7 +614,7 @@ int userdb_by_name(const char *name, UserDBFlags flags, UserRecord **ret) { iterator->nss_lock = r; /* Client-side NSS fallback */ - r = nss_user_record_by_name(name, ret); + r = nss_user_record_by_name(name, !FLAGS_SET(flags, USERDB_AVOID_SHADOW), ret); if (r >= 0) return r; } @@ -661,7 +661,7 @@ int userdb_by_uid(uid_t uid, UserDBFlags flags, UserRecord **ret) { iterator->nss_lock = r; /* Client-side NSS fallback */ - r = nss_user_record_by_uid(uid, ret); + r = nss_user_record_by_uid(uid, !FLAGS_SET(flags, USERDB_AVOID_SHADOW), ret); if (r >= 0) return r; } @@ -819,7 +819,7 @@ int groupdb_by_name(const char *name, UserDBFlags flags, GroupRecord **ret) { if (r >= 0 || r == -EBUSY) { iterator->nss_lock = r; - r = nss_group_record_by_name(name, ret); + r = nss_group_record_by_name(name, !FLAGS_SET(flags, USERDB_AVOID_SHADOW), ret); if (r >= 0) return r; } @@ -865,7 +865,7 @@ int groupdb_by_gid(gid_t gid, UserDBFlags flags, GroupRecord **ret) { if (r >= 0 || r == -EBUSY) { iterator->nss_lock = r; - r = nss_group_record_by_gid(gid, ret); + r = nss_group_record_by_gid(gid, !FLAGS_SET(flags, USERDB_AVOID_SHADOW), ret); if (r >= 0) return r; } @@ -1046,7 +1046,7 @@ int membershipdb_by_group(const char *name, UserDBFlags flags, UserDBIterator ** return iterator->nss_lock; /* We ignore all errors here, since the group might be defined by a userdb native service, and we queried them already above. */ - (void) nss_group_record_by_name(name, &gr); + (void) nss_group_record_by_name(name, false, &gr); if (gr) { iterator->members_of_group = strv_copy(gr->members); if (!iterator->members_of_group) diff --git a/src/shared/userdb.h b/src/shared/userdb.h index 4288b0ff95..8af31aa86c 100644 --- a/src/shared/userdb.h +++ b/src/shared/userdb.h @@ -16,9 +16,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(UserDBIterator*, userdb_iterator_free); typedef enum UserDBFlags { USERDB_AVOID_NSS = 1 << 0, /* don't do client-side nor server-side NSS */ - USERDB_AVOID_DYNAMIC_USER = 1 << 1, /* exclude looking up in io.systemd.DynamicUser */ - USERDB_AVOID_MULTIPLEXER = 1 << 2, /* exclude looking up via io.systemd.Multiplexer */ - USERDB_DONT_SYNTHESIZE = 1 << 3, /* don't synthesize root/nobody */ + USERDB_AVOID_SHADOW = 1 << 1, /* don't do client-side shadow calls (server side might happen though) */ + USERDB_AVOID_DYNAMIC_USER = 1 << 2, /* exclude looking up in io.systemd.DynamicUser */ + USERDB_AVOID_MULTIPLEXER = 1 << 3, /* exclude looking up via io.systemd.Multiplexer */ + USERDB_DONT_SYNTHESIZE = 1 << 4, /* don't synthesize root/nobody */ } UserDBFlags; int userdb_by_name(const char *name, UserDBFlags flags, UserRecord **ret); diff --git a/src/userdb/userwork.c b/src/userdb/userwork.c index 3bc5ecc1d0..053448a718 100644 --- a/src/userdb/userwork.c +++ b/src/userdb/userwork.c @@ -137,9 +137,9 @@ static int vl_method_get_user_record(Varlink *link, JsonVariant *parameters, Var if (streq_ptr(p.service, "io.systemd.NameServiceSwitch")) { if (uid_is_valid(p.uid)) - r = nss_user_record_by_uid(p.uid, &hr); + r = nss_user_record_by_uid(p.uid, true, &hr); else if (p.user_name) - r = nss_user_record_by_name(p.user_name, &hr); + r = nss_user_record_by_name(p.user_name, true, &hr); else { _cleanup_(json_variant_unrefp) JsonVariant *last = NULL; @@ -324,9 +324,9 @@ static int vl_method_get_group_record(Varlink *link, JsonVariant *parameters, Va if (streq_ptr(p.service, "io.systemd.NameServiceSwitch")) { if (gid_is_valid(p.gid)) - r = nss_group_record_by_gid(p.gid, &g); + r = nss_group_record_by_gid(p.gid, true, &g); else if (p.group_name) - r = nss_group_record_by_name(p.group_name, &g); + r = nss_group_record_by_name(p.group_name, true, &g); else { _cleanup_(json_variant_unrefp) JsonVariant *last = NULL; @@ -467,7 +467,7 @@ static int vl_method_get_memberships(Varlink *link, JsonVariant *parameters, Var const char *last = NULL; char **i; - r = nss_group_record_by_name(p.group_name, &g); + r = nss_group_record_by_name(p.group_name, true, &g); if (r == -ESRCH) return varlink_error(link, "io.systemd.UserDatabase.NoRecordFound", NULL); if (r < 0) |