user-util: rework get_user_creds()

Let's fold get_user_creds_clean() into get_user_creds(), and introduce a
flags argument for it to select "clean" behaviour. This flags parameter
also learns to other new flags:

- USER_CREDS_SYNTHESIZE_FALLBACK: in this mode the user records for
  root/nobody are only synthesized as fallback. Normally, the synthesized
  records take precedence over what is in the user database.  With this
  flag set this is reversed, and the user database takes precedence, and
  the synthesized records are only used if they are missing there. This
  flag should be set in cases where doing NSS is deemed safe, and where
  there's interest in knowing the correct shell, for example if the
  admin changed root's shell to zsh or suchlike.

- USER_CREDS_ALLOW_MISSING: if set, and a UID/GID is specified by
  numeric value, and there's no user/group record for it accept it
  anyway. This allows us to fix #9767

This then also ports all users to set the most appropriate flags.

Fixes: #9767

[zj: remove one isempty() call]
This commit is contained in:
Lennart Poettering
2018-08-20 15:58:21 +02:00
committed by Zbigniew Jędrzejewski-Szmek
parent 163a035aa6
commit fafff8f1ff
21 changed files with 146 additions and 106 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ static void test_add_acls_for_user(void) {
if (getuid() == 0) {
const char *nobody = NOBODY_USER_NAME;
r = get_user_creds(&nobody, &uid, NULL, NULL, NULL);
r = get_user_creds(&nobody, &uid, NULL, NULL, NULL, 0);
if (r < 0)
uid = 0;
} else
+1 -1
View File
@@ -9,7 +9,7 @@ int main(int argc, char *argv[]) {
int r;
const char* name = argv[1] ?: NOBODY_USER_NAME;
r = get_user_creds(&name, &uid, NULL, NULL, NULL);
r = get_user_creds(&name, &uid, NULL, NULL, NULL, 0);
if (r < 0) {
log_full_errno(r == -ESRCH ? LOG_NOTICE : LOG_ERR,
r, "Failed to resolve \"%s\": %m", name);
+2 -2
View File
@@ -159,7 +159,7 @@ static void test_get_user_creds_one(const char *id, const char *name, uid_t uid,
log_info("/* %s(\"%s\", \"%s\", "UID_FMT", "GID_FMT", \"%s\", \"%s\") */",
__func__, id, name, uid, gid, home, shell);
r = get_user_creds(&id, &ruid, &rgid, &rhome, &rshell);
r = get_user_creds(&id, &ruid, &rgid, &rhome, &rshell, 0);
log_info_errno(r, "got \"%s\", "UID_FMT", "GID_FMT", \"%s\", \"%s\": %m",
id, ruid, rgid, strnull(rhome), strnull(rshell));
if (!synthesize_nobody() && streq(name, NOBODY_USER_NAME)) {
@@ -180,7 +180,7 @@ static void test_get_group_creds_one(const char *id, const char *name, gid_t gid
log_info("/* %s(\"%s\", \"%s\", "GID_FMT") */", __func__, id, name, gid);
r = get_group_creds(&id, &rgid);
r = get_group_creds(&id, &rgid, 0);
log_info_errno(r, "got \"%s\", "GID_FMT": %m", id, rgid);
if (!synthesize_nobody() && streq(name, NOBODY_GROUP_NAME)) {
log_info("(skipping detailed tests because nobody is not synthesized)");