summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-04-11 16:08:33 +0200
committerGitHub <noreply@github.com>2020-04-11 16:08:33 +0200
commit2d9123cebddfee7cff3052061517c495c5e359cd (patch)
treec2af1810cd0baf0ce801e4e26aba63eb2a0649af
parentMerge pull request #15392 from keszybz/flag-helper (diff)
parentlogind: avoid shadow lookups when doing userdb client side (diff)
downloadsystemd-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.c1
-rw-r--r--src/login/logind-core.c4
-rw-r--r--src/nss-systemd/nss-systemd.c2
-rw-r--r--src/nss-systemd/userdb-glue.c4
-rw-r--r--src/shared/group-record-nss.c52
-rw-r--r--src/shared/group-record-nss.h4
-rw-r--r--src/shared/user-record-nss.c48
-rw-r--r--src/shared/user-record-nss.h4
-rw-r--r--src/shared/userdb.c10
-rw-r--r--src/shared/userdb.h7
-rw-r--r--src/userdb/userwork.c10
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)