New upstream version 4.7

This commit is contained in:
Balint Reczey
2019-06-23 22:06:37 +02:00
parent b0729855e8
commit b28d45d2bd
10587 changed files with 152812 additions and 381179 deletions
+130 -28
View File
@@ -60,6 +60,7 @@
#include "getdef.h"
#include "groupio.h"
#include "nscd.h"
#include "sssd.h"
#include "prototypes.h"
#include "pwauth.h"
#include "pwio.h"
@@ -164,6 +165,7 @@ static bool
oflg = false, /* permit non-unique user ID to be specified with -u */
rflg = false, /* create a system account */
sflg = false, /* shell program for new account */
subvolflg = false, /* create subvolume home on BTRFS */
uflg = false, /* specify user ID for new account */
Uflg = false; /* create a group having the same name as the user */
@@ -343,7 +345,7 @@ static void fail_exit (int code)
static void get_defaults (void)
{
FILE *fp;
char* default_file = USER_DEFAULTS_FILE;
char *default_file = USER_DEFAULTS_FILE;
char buf[1024];
char *cp;
@@ -353,6 +355,8 @@ static void get_defaults (void)
len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2;
default_file = malloc(len);
if (default_file == NULL)
return;
wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE);
assert (wlen == (int) len -1);
}
@@ -363,7 +367,7 @@ static void get_defaults (void)
fp = fopen (default_file, "r");
if (NULL == fp) {
return;
goto getdef_err;
}
/*
@@ -474,7 +478,7 @@ static void get_defaults (void)
}
}
(void) fclose (fp);
getdef_err:
if(prefix[0]) {
free(default_file);
}
@@ -509,8 +513,8 @@ static int set_defaults (void)
FILE *ifp;
FILE *ofp;
char buf[1024];
char* new_file = NEW_USER_FILE;
char* default_file = USER_DEFAULTS_FILE;
char *new_file = NULL;
char *default_file = USER_DEFAULTS_FILE;
char *cp;
int ofd;
int wlen;
@@ -521,17 +525,30 @@ static int set_defaults (void)
bool out_shell = false;
bool out_skel = false;
bool out_create_mail_spool = false;
size_t len;
int ret = -1;
len = strlen(prefix) + strlen(NEW_USER_FILE) + 2;
new_file = malloc(len);
if (new_file == NULL) {
fprintf (stderr,
_("%s: cannot create new defaults file: %s\n"),
Prog, strerror(errno));
return -1;
}
wlen = snprintf(new_file, len, "%s%s%s", prefix, prefix[0]?"/":"", NEW_USER_FILE);
assert (wlen <= (int) len -1);
if(prefix[0]) {
size_t len;
len = strlen(prefix) + strlen(NEW_USER_FILE) + 2;
new_file = malloc(len);
wlen = snprintf(new_file, len, "%s/%s", prefix, NEW_USER_FILE);
assert (wlen == (int) len -1);
len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2;
default_file = malloc(len);
if (default_file == NULL) {
fprintf (stderr,
_("%s: cannot create new defaults file: %s\n"),
Prog, strerror(errno));
goto setdef_err;
}
wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE);
assert (wlen == (int) len -1);
}
@@ -544,7 +561,7 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: cannot create new defaults file\n"),
Prog);
return -1;
goto setdef_err;
}
ofp = fdopen (ofd, "w");
@@ -552,7 +569,7 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: cannot open new defaults file\n"),
Prog);
return -1;
goto setdef_err;
}
/*
@@ -579,7 +596,7 @@ static int set_defaults (void)
_("%s: line too long in %s: %s..."),
Prog, default_file, buf);
(void) fclose (ifp);
return -1;
goto setdef_err;
}
}
@@ -643,7 +660,7 @@ static int set_defaults (void)
|| (fsync (fileno (ofp)) != 0)
|| (fclose (ofp) != 0)) {
unlink (new_file);
return -1;
goto setdef_err;
}
/*
@@ -658,7 +675,7 @@ static int set_defaults (void)
_("%s: Cannot create backup file (%s): %s\n"),
Prog, buf, strerror (err));
unlink (new_file);
return -1;
goto setdef_err;
}
/*
@@ -669,7 +686,7 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: rename: %s: %s\n"),
Prog, new_file, strerror (err));
return -1;
goto setdef_err;
}
#ifdef WITH_AUDIT
audit_logger (AUDIT_USYS_CONFIG, Prog,
@@ -683,13 +700,14 @@ static int set_defaults (void)
(unsigned int) def_group, def_home, def_shell,
def_inactive, def_expire, def_template,
def_create_mail_spool));
ret = 0;
setdef_err:
free(new_file);
if(prefix[0]) {
free(new_file);
free(default_file);
}
return 0;
return ret;
}
/*
@@ -805,6 +823,9 @@ static void usage (int status)
Prog, Prog, Prog);
(void) fputs (_(" -b, --base-dir BASE_DIR base directory for the home directory of the\n"
" new account\n"), usageout);
#ifdef WITH_BTRFS
(void) fputs (_(" --btrfs-subvolume-home use BTRFS subvolume for home directory\n"), usageout);
#endif
(void) fputs (_(" -c, --comment COMMENT GECOS field of the new account\n"), usageout);
(void) fputs (_(" -d, --home-dir HOME_DIR home directory of the new account\n"), usageout);
(void) fputs (_(" -D, --defaults print or change default useradd configuration\n"), usageout);
@@ -1085,6 +1106,9 @@ static void process_flags (int argc, char **argv)
int c;
static struct option long_options[] = {
{"base-dir", required_argument, NULL, 'b'},
#ifdef WITH_BTRFS
{"btrfs-subvolume-home", no_argument, NULL, 200},
#endif
{"comment", required_argument, NULL, 'c'},
{"home-dir", required_argument, NULL, 'd'},
{"defaults", no_argument, NULL, 'D'},
@@ -1131,6 +1155,9 @@ static void process_flags (int argc, char **argv)
def_home = optarg;
bflg = true;
break;
case 200:
subvolflg = true;
break;
case 'c':
if (!VALID (optarg)) {
fprintf (stderr,
@@ -1846,11 +1873,18 @@ static void lastlog_reset (uid_t uid)
struct lastlog ll;
int fd;
off_t offset_uid = (off_t) (sizeof ll) * uid;
uid_t max_uid;
if (access (LASTLOG_FILE, F_OK) != 0) {
return;
}
max_uid = (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL);
if (uid > max_uid) {
/* do not touch lastlog for large uids */
return;
}
memzero (&ll, sizeof (ll));
fd = open (LASTLOG_FILE, O_RDWR);
@@ -2018,6 +2052,19 @@ static void usr_update (void)
static void create_home (void)
{
if (access (prefix_user_home, F_OK) != 0) {
char path[strlen (prefix_user_home) + 2];
char *bhome, *cp;
path[0] = '\0';
bhome = strdup (prefix_user_home);
if (!bhome) {
fprintf (stderr,
_("%s: error while duplicating string %s\n"),
Prog, user_home);
fail_exit (E_HOMEDIR);
}
++bhome;
#ifdef WITH_SELINUX
if (set_selinux_file_context (prefix_user_home) != 0) {
fprintf (stderr,
@@ -2026,19 +2073,73 @@ static void create_home (void)
fail_exit (E_HOMEDIR);
}
#endif
/* XXX - create missing parent directories. --marekm */
if (mkdir (prefix_user_home, 0) != 0) {
/* Check for every part of the path, if the directory
exists. If not, create it with permissions 755 and
owner root:root.
*/
cp = strtok (bhome, "/");
while (cp) {
strcat (path, "/");
strcat (path, cp);
if (access (path, F_OK) != 0) {
/* Check if parent directory is BTRFS, fail if requesting
subvolume but no BTRFS. The paths cound be different by the
trailing slash
*/
#if WITH_BTRFS
if (subvolflg && (strlen(prefix_user_home) - (int)strlen(path)) <= 1) {
char *btrfs_check = strdup(path);
if (!btrfs_check) {
fprintf (stderr,
_("%s: error while duplicating string in BTRFS check %s\n"),
Prog, path);
fail_exit (E_HOMEDIR);
}
btrfs_check[strlen(path) - strlen(cp) - 1] = '\0';
if (is_btrfs(btrfs_check) <= 0) {
fprintf (stderr,
_("%s: home directory \"%s\" must be mounted on BTRFS\n"),
Prog, path);
fail_exit (E_HOMEDIR);
}
// make subvolume to mount for user instead of directory
if (btrfs_create_subvolume(path)) {
fprintf (stderr,
_("%s: failed to create BTRFS subvolume: %s\n"),
Prog, path);
fail_exit (E_HOMEDIR);
}
}
else
#endif
if (mkdir (path, 0) != 0) {
fprintf (stderr,
_("%s: cannot create directory %s\n"),
Prog, prefix_user_home);
_("%s: cannot create directory %s\n"),
Prog, path);
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, Prog,
"adding home directory",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
"adding home directory",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
#endif
fail_exit (E_HOMEDIR);
}
if (chown (path, 0, 0) < 0) {
fprintf (stderr,
_("%s: warning: chown on `%s' failed: %m\n"),
Prog, path);
}
if (chmod (path, 0755) < 0) {
fprintf (stderr,
_("%s: warning: chmod on `%s' failed: %m\n"),
Prog, path);
}
}
cp = strtok (NULL, "/");
}
(void) chown (prefix_user_home, user_id, user_gid);
chmod (prefix_user_home,
0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK));
@@ -2389,6 +2490,7 @@ int main (int argc, char **argv)
nscd_flush_cache ("passwd");
nscd_flush_cache ("group");
sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP);
return E_SUCCESS;
}