execute: move suppression of HOME=/ and SHELL=/bin/nologin into user-util.c

This adds a new call get_user_creds_clean(), which is just like
get_user_creds() but returns NULL in the home/shell parameters if they contain
no useful information. This code previously lived in execute.c, but by
generalizing this we can reuse it in run.c.
This commit is contained in:
Lennart Poettering 2016-08-25 10:24:10 +02:00 committed by Djalal Harouni
parent 07689d5d2c
commit be39ccf3a0
4 changed files with 46 additions and 19 deletions

View File

@ -31,14 +31,15 @@
#include <unistd.h>
#include <utmp.h>
#include "missing.h"
#include "alloc-util.h"
#include "fd-util.h"
#include "formats-util.h"
#include "macro.h"
#include "missing.h"
#include "parse-util.h"
#include "path-util.h"
#include "string-util.h"
#include "strv.h"
#include "user-util.h"
#include "utf8.h"
@ -175,6 +176,35 @@ int get_user_creds(
return 0;
}
int get_user_creds_clean(
const char **username,
uid_t *uid, gid_t *gid,
const char **home,
const char **shell) {
int r;
/* Like get_user_creds(), but resets home/shell to NULL if they don't contain anything relevant. */
r = get_user_creds(username, uid, gid, home, shell);
if (r < 0)
return r;
if (shell &&
(isempty(*shell) || PATH_IN_SET(*shell,
"/bin/nologin",
"/sbin/nologin",
"/usr/bin/nologin",
"/usr/sbin/nologin")))
*shell = NULL;
if (home &&
(isempty(*home) || path_equal(*home, "/")))
*home = NULL;
return 0;
}
int get_group_creds(const char **groupname, gid_t *gid) {
struct group *g;
gid_t id;

View File

@ -40,6 +40,7 @@ char* getlogname_malloc(void);
char* getusername_malloc(void);
int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
int get_user_creds_clean(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
int get_group_creds(const char **groupname, gid_t *gid);
char* uid_to_name(uid_t uid);

View File

@ -2051,22 +2051,14 @@ static int exec_child(
} else {
if (context->user) {
username = context->user;
r = get_user_creds(&username, &uid, &gid, &home, &shell);
r = get_user_creds_clean(&username, &uid, &gid, &home, &shell);
if (r < 0) {
*exit_status = EXIT_USER;
return r;
}
/* Don't set $HOME or $SHELL if they are are not particularly enlightening anyway. */
if (isempty(home) || path_equal(home, "/"))
home = NULL;
if (isempty(shell) || PATH_IN_SET(shell,
"/bin/nologin",
"/sbin/nologin",
"/usr/bin/nologin",
"/usr/sbin/nologin"))
shell = NULL;
/* Note that we don't set $HOME or $SHELL if they are are not particularly enlightening anyway
* (i.e. are "/" or "/bin/nologin"). */
}
if (context->group) {

View File

@ -1168,17 +1168,21 @@ static int start_transient_scope(
uid_t uid;
gid_t gid;
r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell);
r = get_user_creds_clean(&arg_exec_user, &uid, &gid, &home, &shell);
if (r < 0)
return log_error_errno(r, "Failed to resolve user %s: %m", arg_exec_user);
r = strv_extendf(&user_env, "HOME=%s", home);
if (r < 0)
return log_oom();
if (home) {
r = strv_extendf(&user_env, "HOME=%s", home);
if (r < 0)
return log_oom();
}
r = strv_extendf(&user_env, "SHELL=%s", shell);
if (r < 0)
return log_oom();
if (shell) {
r = strv_extendf(&user_env, "SHELL=%s", shell);
if (r < 0)
return log_oom();
}
r = strv_extendf(&user_env, "USER=%s", arg_exec_user);
if (r < 0)