New upstream version 4.11.1+dfsg1
This commit is contained in:
+118
-89
@@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
|
||||
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
||||
* Copyright (c) 2000 - 2006, Tomasz Kłoczko
|
||||
* Copyright (c) 2007 - 2012, Nicolas François
|
||||
* All rights reserved.
|
||||
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2000 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2012, Nicolas François
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the copyright holders or contributors may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -41,6 +18,7 @@
|
||||
#include <getopt.h>
|
||||
#include <grp.h>
|
||||
#include <lastlog.h>
|
||||
#include <libgen.h>
|
||||
#include <pwd.h>
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
@@ -78,6 +56,7 @@
|
||||
#ifdef WITH_TCB
|
||||
#include "tcbfuncs.h"
|
||||
#endif
|
||||
#include "shadowlog.h"
|
||||
|
||||
#ifndef SKEL_DIR
|
||||
#define SKEL_DIR "/etc/skel"
|
||||
@@ -96,7 +75,6 @@
|
||||
* Global variables
|
||||
*/
|
||||
const char *Prog;
|
||||
FILE *shadow_logfd = NULL;
|
||||
|
||||
/*
|
||||
* These defaults are used if there is no defaults file.
|
||||
@@ -107,6 +85,7 @@ static const char *def_home = "/home";
|
||||
static const char *def_shell = "/bin/bash";
|
||||
static const char *def_template = SKEL_DIR;
|
||||
static const char *def_create_mail_spool = "yes";
|
||||
static const char *def_log_init = "yes";
|
||||
|
||||
static long def_inactive = -1;
|
||||
static const char *def_expire = "";
|
||||
@@ -142,9 +121,7 @@ static bool is_sub_gid = false;
|
||||
static bool sub_uid_locked = false;
|
||||
static bool sub_gid_locked = false;
|
||||
static uid_t sub_uid_start; /* New subordinate uid range */
|
||||
static unsigned long sub_uid_count;
|
||||
static gid_t sub_gid_start; /* New subordinate gid range */
|
||||
static unsigned long sub_gid_count;
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
static bool pw_locked = false;
|
||||
static bool gr_locked = false;
|
||||
@@ -209,6 +186,7 @@ static bool home_added = false;
|
||||
#define DEXPIRE "EXPIRE="
|
||||
#define DSKEL "SKEL="
|
||||
#define DCREATE_MAIL_SPOOL "CREATE_MAIL_SPOOL="
|
||||
#define DLOG_INIT "LOG_INIT="
|
||||
|
||||
/* local function prototypes */
|
||||
static void fail_exit (int);
|
||||
@@ -234,7 +212,7 @@ static void open_shadow (void);
|
||||
static void faillog_reset (uid_t);
|
||||
static void lastlog_reset (uid_t);
|
||||
static void tallylog_reset (const char *);
|
||||
static void usr_update (void);
|
||||
static void usr_update (unsigned long subuid_count, unsigned long subgid_count);
|
||||
static void create_home (void);
|
||||
static void create_mail (void);
|
||||
static void check_uid_range(int rflg, uid_t user_id);
|
||||
@@ -362,7 +340,7 @@ static void get_defaults (void)
|
||||
char buf[1024];
|
||||
char *cp;
|
||||
|
||||
if(prefix[0]) {
|
||||
if (prefix[0]) {
|
||||
size_t len;
|
||||
int wlen;
|
||||
|
||||
@@ -415,7 +393,6 @@ static void get_defaults (void)
|
||||
} else {
|
||||
def_group = grp->gr_gid;
|
||||
def_gname = xstrdup (grp->gr_name);
|
||||
gr_free(grp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,8 +440,8 @@ static void get_defaults (void)
|
||||
if ('\0' == *cp) {
|
||||
cp = SKEL_DIR; /* XXX warning: const */
|
||||
}
|
||||
|
||||
if(prefix[0]) {
|
||||
|
||||
if (prefix[0]) {
|
||||
size_t len;
|
||||
int wlen;
|
||||
char* _def_template; /* avoid const warning */
|
||||
@@ -490,10 +467,20 @@ static void get_defaults (void)
|
||||
|
||||
def_create_mail_spool = xstrdup (cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* By default do we add the user to the lastlog and faillog databases ?
|
||||
*/
|
||||
else if (MATCH (buf, DLOG_INIT)) {
|
||||
if (*cp == '\0') {
|
||||
cp = def_log_init; /* XXX warning: const */
|
||||
}
|
||||
def_log_init = xstrdup (cp);
|
||||
}
|
||||
}
|
||||
(void) fclose (fp);
|
||||
getdef_err:
|
||||
if(prefix[0]) {
|
||||
if (prefix[0]) {
|
||||
free(default_file);
|
||||
}
|
||||
}
|
||||
@@ -513,6 +500,7 @@ static void show_defaults (void)
|
||||
printf ("SHELL=%s\n", def_shell);
|
||||
printf ("SKEL=%s\n", def_template);
|
||||
printf ("CREATE_MAIL_SPOOL=%s\n", def_create_mail_spool);
|
||||
printf ("LOG_INIT=%s\n", def_log_init);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -528,6 +516,7 @@ static int set_defaults (void)
|
||||
FILE *ofp;
|
||||
char buf[1024];
|
||||
char *new_file = NULL;
|
||||
char *new_file_dup = NULL;
|
||||
char *default_file = USER_DEFAULTS_FILE;
|
||||
char *cp;
|
||||
int ofd;
|
||||
@@ -539,6 +528,7 @@ static int set_defaults (void)
|
||||
bool out_shell = false;
|
||||
bool out_skel = false;
|
||||
bool out_create_mail_spool = false;
|
||||
bool out_log_init = false;
|
||||
size_t len;
|
||||
int ret = -1;
|
||||
|
||||
@@ -554,7 +544,7 @@ static int set_defaults (void)
|
||||
wlen = snprintf(new_file, len, "%s%s%s", prefix, prefix[0]?"/":"", NEW_USER_FILE);
|
||||
assert (wlen <= (int) len -1);
|
||||
|
||||
if(prefix[0]) {
|
||||
if (prefix[0]) {
|
||||
len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2;
|
||||
default_file = malloc(len);
|
||||
if (default_file == NULL) {
|
||||
@@ -567,6 +557,24 @@ static int set_defaults (void)
|
||||
assert (wlen == (int) len -1);
|
||||
}
|
||||
|
||||
new_file_dup = strdup(new_file);
|
||||
if (new_file_dup == NULL) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot create directory for defaults file\n"),
|
||||
Prog);
|
||||
goto setdef_err;
|
||||
}
|
||||
|
||||
ret = mkdir(dirname(new_file_dup), 0755);
|
||||
if (-1 == ret && EEXIST != errno) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot create directory for defaults file\n"),
|
||||
Prog);
|
||||
free(new_file_dup);
|
||||
goto setdef_err;
|
||||
}
|
||||
free(new_file_dup);
|
||||
|
||||
/*
|
||||
* Create a temporary file to copy the new output to.
|
||||
*/
|
||||
@@ -638,6 +646,12 @@ static int set_defaults (void)
|
||||
DCREATE_MAIL_SPOOL "%s\n",
|
||||
def_create_mail_spool);
|
||||
out_create_mail_spool = true;
|
||||
} else if (!out_log_init
|
||||
&& MATCH (buf, DLOG_INIT)) {
|
||||
fprintf (ofp,
|
||||
DLOG_INIT "%s\n",
|
||||
def_log_init);
|
||||
out_log_init = true;
|
||||
} else
|
||||
fprintf (ofp, "%s\n", buf);
|
||||
}
|
||||
@@ -664,7 +678,8 @@ static int set_defaults (void)
|
||||
|
||||
if (!out_create_mail_spool)
|
||||
fprintf (ofp, DCREATE_MAIL_SPOOL "%s\n", def_create_mail_spool);
|
||||
|
||||
if (!out_log_init)
|
||||
fprintf (ofp, DLOG_INIT "%s\n", def_log_init);
|
||||
/*
|
||||
* Flush and close the file. Check for errors to make certain
|
||||
* the new file is intact.
|
||||
@@ -710,14 +725,14 @@ static int set_defaults (void)
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"useradd defaults: GROUP=%u, HOME=%s, SHELL=%s, INACTIVE=%ld, "
|
||||
"EXPIRE=%s, SKEL=%s, CREATE_MAIL_SPOOL=%s",
|
||||
"EXPIRE=%s, SKEL=%s, CREATE_MAIL_SPOOL=%s, LOG_INIT=%s",
|
||||
(unsigned int) def_group, def_home, def_shell,
|
||||
def_inactive, def_expire, def_template,
|
||||
def_create_mail_spool));
|
||||
def_create_mail_spool, def_log_init));
|
||||
ret = 0;
|
||||
setdef_err:
|
||||
free(new_file);
|
||||
if(prefix[0]) {
|
||||
if (prefix[0]) {
|
||||
free(default_file);
|
||||
}
|
||||
|
||||
@@ -1044,7 +1059,7 @@ static void grp_update (void)
|
||||
fail_exit (E_GRP_UPDATE); /* XXX */
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Add the username to the list of group members and
|
||||
* update the group entry to reflect the change.
|
||||
*/
|
||||
@@ -1119,7 +1134,7 @@ static void grp_update (void)
|
||||
fail_exit (E_GRP_UPDATE); /* XXX */
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Add the username to the list of group members and
|
||||
* update the group entry to reflect the change.
|
||||
*/
|
||||
@@ -1529,7 +1544,7 @@ static void process_flags (int argc, char **argv)
|
||||
|
||||
user_home = uh;
|
||||
}
|
||||
if(prefix[0]) {
|
||||
if (prefix[0]) {
|
||||
size_t len = strlen(prefix) + strlen(user_home) + 2;
|
||||
int wlen;
|
||||
char* _prefix_user_home; /* to avoid const warning */
|
||||
@@ -1557,6 +1572,14 @@ static void process_flags (int argc, char **argv)
|
||||
|
||||
create_mail_spool = def_create_mail_spool;
|
||||
|
||||
if (!lflg) {
|
||||
/* If we are missing the flag lflg aka -l, check the defaults
|
||||
* file to see if we need to disable it as a default*/
|
||||
if (strcmp (def_log_init, "no") == 0) {
|
||||
lflg = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rflg) {
|
||||
/* for system accounts defaults are ignored and we
|
||||
* do not create a home dir */
|
||||
@@ -2084,7 +2107,7 @@ static void tallylog_reset (const char *user_name)
|
||||
* usr_update() creates the password file entries for this user
|
||||
* and will update the group entries if required.
|
||||
*/
|
||||
static void usr_update (void)
|
||||
static void usr_update (unsigned long subuid_count, unsigned long subgid_count)
|
||||
{
|
||||
struct passwd pwent;
|
||||
struct spwd spent;
|
||||
@@ -2147,14 +2170,14 @@ static void usr_update (void)
|
||||
}
|
||||
#ifdef ENABLE_SUBIDS
|
||||
if (is_sub_uid &&
|
||||
(sub_uid_add(user_name, sub_uid_start, sub_uid_count) == 0)) {
|
||||
(sub_uid_add(user_name, sub_uid_start, subuid_count) == 0)) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to prepare the new %s entry\n"),
|
||||
Prog, sub_uid_dbname ());
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
}
|
||||
if (is_sub_gid &&
|
||||
(sub_gid_add(user_name, sub_gid_start, sub_gid_count) == 0)) {
|
||||
(sub_gid_add(user_name, sub_gid_start, subgid_count) == 0)) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to prepare the new %s entry\n"),
|
||||
Prog, sub_uid_dbname ());
|
||||
@@ -2322,11 +2345,16 @@ static void create_mail (void)
|
||||
mode_t mode;
|
||||
|
||||
spool = getdef_str ("MAIL_DIR");
|
||||
#ifdef MAIL_SPOOL_DIR
|
||||
if ((NULL == spool) && (getdef_str ("MAIL_FILE") == NULL)) {
|
||||
spool = MAIL_SPOOL_DIR;
|
||||
}
|
||||
#endif /* MAIL_SPOOL_DIR */
|
||||
if (NULL == spool) {
|
||||
spool = "/var/mail";
|
||||
return;
|
||||
}
|
||||
file = alloca (strlen (prefix) + strlen (spool) + strlen (user_name) + 2);
|
||||
if(prefix[0])
|
||||
if (prefix[0])
|
||||
sprintf (file, "%s/%s/%s", prefix, spool, user_name);
|
||||
else
|
||||
sprintf (file, "%s/%s", spool, user_name);
|
||||
@@ -2380,18 +2408,18 @@ static void check_uid_range(int rflg, uid_t user_id)
|
||||
{
|
||||
uid_t uid_min ;
|
||||
uid_t uid_max ;
|
||||
if(rflg){
|
||||
if (rflg) {
|
||||
uid_min = (uid_t)getdef_ulong("SYS_UID_MIN",101UL);
|
||||
uid_max = (uid_t)getdef_ulong("SYS_UID_MAX",getdef_ulong("UID_MIN",1000UL)-1);
|
||||
if(uid_min <= uid_max){
|
||||
if(user_id < uid_min || user_id >uid_max)
|
||||
if (uid_min <= uid_max) {
|
||||
if (user_id < uid_min || user_id >uid_max)
|
||||
fprintf(stderr, _("%s warning: %s's uid %d outside of the SYS_UID_MIN %d and SYS_UID_MAX %d range.\n"), Prog, user_name, user_id, uid_min, uid_max);
|
||||
}
|
||||
}else{
|
||||
uid_min = (uid_t)getdef_ulong("UID_MIN", 1000UL);
|
||||
uid_max = (uid_t)getdef_ulong("UID_MAX", 6000UL);
|
||||
if(uid_min <= uid_max){
|
||||
if(user_id < uid_min || user_id >uid_max)
|
||||
if (uid_min <= uid_max) {
|
||||
if (user_id < uid_min || user_id >uid_max)
|
||||
fprintf(stderr, _("%s warning: %s's uid %d outside of the UID_MIN %d and UID_MAX %d range.\n"), Prog, user_name, user_id, uid_min, uid_max);
|
||||
}
|
||||
}
|
||||
@@ -2412,15 +2440,16 @@ int main (int argc, char **argv)
|
||||
#ifdef ENABLE_SUBIDS
|
||||
uid_t uid_min;
|
||||
uid_t uid_max;
|
||||
unsigned long subuid_count;
|
||||
unsigned long subgid_count;
|
||||
#endif
|
||||
unsigned long subuid_count = 0;
|
||||
unsigned long subgid_count = 0;
|
||||
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
Prog = Basename (argv[0]);
|
||||
shadow_logfd = stderr;
|
||||
log_set_progname(Prog);
|
||||
log_set_logfd(stderr);
|
||||
|
||||
(void) setlocale (LC_ALL, "");
|
||||
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
@@ -2473,14 +2502,14 @@ int main (int argc, char **argv)
|
||||
{
|
||||
struct passwd *pampw;
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (pampw == NULL) {
|
||||
if (pampw == NULL && getuid ()) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
fail_exit (1);
|
||||
}
|
||||
|
||||
retval = pam_start ("useradd", pampw->pw_name, &conv, &pamh);
|
||||
retval = pam_start ("useradd", pampw?pampw->pw_name:"root", &conv, &pamh);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
@@ -2589,7 +2618,7 @@ int main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if(uflg)
|
||||
if (uflg)
|
||||
check_uid_range(rflg,user_id);
|
||||
#ifdef WITH_TCB
|
||||
if (getdef_bool ("USE_TCB")) {
|
||||
@@ -2616,16 +2645,16 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
if (is_sub_uid && sub_uid_count != 0) {
|
||||
if (find_new_sub_uids(&sub_uid_start, &sub_uid_count) < 0) {
|
||||
if (is_sub_uid && subuid_count != 0) {
|
||||
if (find_new_sub_uids(&sub_uid_start, &subuid_count) < 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: can't create subordinate user IDs\n"),
|
||||
Prog);
|
||||
fail_exit(E_SUB_UID_UPDATE);
|
||||
}
|
||||
}
|
||||
if (is_sub_gid && sub_gid_count != 0) {
|
||||
if (find_new_sub_gids(&sub_gid_start, &sub_gid_count) < 0) {
|
||||
if (is_sub_gid && subgid_count != 0) {
|
||||
if (find_new_sub_gids(&sub_gid_start, &subgid_count) < 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: can't create subordinate group IDs\n"),
|
||||
Prog);
|
||||
@@ -2634,29 +2663,14 @@ int main (int argc, char **argv)
|
||||
}
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
|
||||
usr_update ();
|
||||
|
||||
if (mflg) {
|
||||
create_home ();
|
||||
if (home_added) {
|
||||
copy_tree (def_template, prefix_user_home, false, false,
|
||||
(uid_t)-1, user_id, (gid_t)-1, user_gid);
|
||||
} else {
|
||||
fprintf (stderr,
|
||||
_("%s: warning: the home directory %s already exists.\n"
|
||||
"%s: Not copying any file from skel directory into it.\n"),
|
||||
Prog, user_home, Prog);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Do not create mail directory for system accounts */
|
||||
if (!rflg) {
|
||||
create_mail ();
|
||||
}
|
||||
usr_update (subuid_count, subgid_count);
|
||||
|
||||
close_files ();
|
||||
|
||||
nscd_flush_cache ("passwd");
|
||||
nscd_flush_cache ("group");
|
||||
sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP);
|
||||
|
||||
/*
|
||||
* tallylog_reset needs to be able to lookup
|
||||
* a valid existing user name,
|
||||
@@ -2682,15 +2696,30 @@ int main (int argc, char **argv)
|
||||
}
|
||||
#endif /* WITH_SELINUX */
|
||||
|
||||
if (mflg) {
|
||||
create_home ();
|
||||
if (home_added) {
|
||||
copy_tree (def_template, prefix_user_home, false, true,
|
||||
(uid_t)-1, user_id, (gid_t)-1, user_gid);
|
||||
} else {
|
||||
fprintf (stderr,
|
||||
_("%s: warning: the home directory %s already exists.\n"
|
||||
"%s: Not copying any file from skel directory into it.\n"),
|
||||
Prog, user_home, Prog);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Do not create mail directory for system accounts */
|
||||
if (!rflg) {
|
||||
create_mail ();
|
||||
}
|
||||
|
||||
if (run_parts ("/etc/shadow-maint/useradd-post.d", (char*)user_name,
|
||||
"useradd")) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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