New upstream version 4.7
This commit is contained in:
+130
-28
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user