New upstream version 4.5
This commit is contained in:
+9
-9
@@ -7,9 +7,10 @@ usbindir = ${prefix}/sbin
|
||||
suidperms = 4755
|
||||
sgidperms = 2755
|
||||
|
||||
INCLUDES = \
|
||||
AM_CPPFLAGS = \
|
||||
-I${top_srcdir}/lib \
|
||||
-I$(top_srcdir)/libmisc
|
||||
-I$(top_srcdir)/libmisc \
|
||||
-DLOCALEDIR=\"$(datadir)/locale\"
|
||||
|
||||
# XXX why are login and su in /bin anyway (other than for
|
||||
# historical reasons)?
|
||||
@@ -54,10 +55,10 @@ noinst_PROGRAMS = id sulogin
|
||||
suidbins = su
|
||||
suidubins = chage chfn chsh expiry gpasswd newgrp passwd
|
||||
if ACCT_TOOLS_SETUID
|
||||
suidubins += chage chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
|
||||
suidubins += chage chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
|
||||
endif
|
||||
if ENABLE_SUBIDS
|
||||
suidubins += newgidmap newuidmap
|
||||
suidubins += newgidmap newuidmap
|
||||
endif
|
||||
|
||||
if WITH_TCB
|
||||
@@ -69,7 +70,6 @@ LDADD = $(INTLLIBS) \
|
||||
$(LIBTCB) \
|
||||
$(top_builddir)/libmisc/libmisc.a \
|
||||
$(top_builddir)/lib/libshadow.la
|
||||
AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\"
|
||||
|
||||
if ACCT_TOOLS_SETUID
|
||||
LIBPAM_SUID = $(LIBPAM)
|
||||
@@ -113,7 +113,7 @@ pwunconv_LDADD = $(LDADD) $(LIBSELINUX)
|
||||
su_SOURCES = \
|
||||
su.c \
|
||||
suauth.c
|
||||
su_LDADD = $(LDADD) $(LIBPAM) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
||||
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
||||
sulogin_LDADD = $(LDADD) $(LIBCRYPT)
|
||||
useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR)
|
||||
userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE)
|
||||
@@ -125,14 +125,14 @@ install-am: all-am
|
||||
ln -sf newgrp $(DESTDIR)$(ubindir)/sg
|
||||
ln -sf vipw $(DESTDIR)$(usbindir)/vigr
|
||||
for i in $(suidbins); do \
|
||||
chmod -f $(suidperms) $(DESTDIR)$(bindir)/$$i; \
|
||||
chmod $(suidperms) $(DESTDIR)$(bindir)/$$i; \
|
||||
done
|
||||
for i in $(suidubins); do \
|
||||
chmod -f $(suidperms) $(DESTDIR)$(ubindir)/$$i; \
|
||||
chmod $(suidperms) $(DESTDIR)$(ubindir)/$$i; \
|
||||
done
|
||||
if WITH_TCB
|
||||
for i in $(shadowsgidubins); do \
|
||||
chown root:shadow $(DESTDIR)$(ubindir)/$$i; \
|
||||
chmod -f $(sgidperms) $(DESTDIR)$(ubindir)/$$i; \
|
||||
chmod $(sgidperms) $(DESTDIR)$(ubindir)/$$i; \
|
||||
done
|
||||
endif
|
||||
|
||||
+1
-1
@@ -552,7 +552,7 @@ int main (int argc, char **argv)
|
||||
if (NULL != sp) {
|
||||
newsp = *sp;
|
||||
newsp.sp_pwdp = cp;
|
||||
newsp.sp_lstchg = (long) time ((time_t *)NULL) / SCALE;
|
||||
newsp.sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == newsp.sp_lstchg) {
|
||||
/* Better disable aging than requiring a
|
||||
* password change */
|
||||
|
||||
+4
-4
@@ -496,7 +496,7 @@ static int add_passwd (struct passwd *pwd, const char *password)
|
||||
}
|
||||
spent.sp_pwdp = cp;
|
||||
}
|
||||
spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent.sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent.sp_lstchg) {
|
||||
/* Better disable aging than requiring a password
|
||||
* change */
|
||||
@@ -553,7 +553,7 @@ static int add_passwd (struct passwd *pwd, const char *password)
|
||||
*/
|
||||
spent.sp_pwdp = "!";
|
||||
#endif
|
||||
spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent.sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent.sp_lstchg) {
|
||||
/* Better disable aging than requiring a password change */
|
||||
spent.sp_lstchg = -1;
|
||||
@@ -988,8 +988,8 @@ int main (int argc, char **argv)
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
#ifdef ENABLE_SUBIDS
|
||||
is_sub_uid = sub_uid_file_present ();
|
||||
is_sub_gid = sub_gid_file_present ();
|
||||
is_sub_uid = sub_uid_file_present () && !rflg;
|
||||
is_sub_gid = sub_gid_file_present () && !rflg;
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
|
||||
open_files ();
|
||||
|
||||
+1
-1
@@ -668,7 +668,7 @@ static void update_shadow (void)
|
||||
}
|
||||
#ifndef USE_PAM
|
||||
if (do_update_age) {
|
||||
nsp->sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
nsp->sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == nsp->sp_lstchg) {
|
||||
/* Better disable aging than requiring a password
|
||||
* change */
|
||||
|
||||
@@ -219,6 +219,22 @@ static /*@noreturn@*/void su_failure (const char *tty, bool su_to_root)
|
||||
}
|
||||
closelog ();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_fd = audit_open ();
|
||||
audit_log_acct_message (audit_fd,
|
||||
AUDIT_USER_ROLE_CHANGE,
|
||||
NULL, /* Prog. name */
|
||||
"su",
|
||||
('\0' != caller_name[0]) ? caller_name : "???",
|
||||
AUDIT_NO_ID,
|
||||
"localhost",
|
||||
NULL, /* addr */
|
||||
tty,
|
||||
0); /* result */
|
||||
close (audit_fd);
|
||||
#endif /* WITH_AUDIT */
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
@@ -363,23 +379,38 @@ static void prepare_pam_close_session (void)
|
||||
/* wake child when resumed */
|
||||
kill (pid, SIGCONT);
|
||||
stop = false;
|
||||
} else if ( (pid_t)-1 != pid) {
|
||||
pid_child = 0;
|
||||
}
|
||||
} while (!stop);
|
||||
}
|
||||
|
||||
if (0 != caught) {
|
||||
if (0 != caught && 0 != pid_child) {
|
||||
(void) fputs ("\n", stderr);
|
||||
(void) fputs (_("Session terminated, terminating shell..."),
|
||||
stderr);
|
||||
(void) kill (-pid_child, caught);
|
||||
|
||||
snprintf (kill_msg, 256, _(" ...killed.\n"));
|
||||
snprintf (wait_msg, 256, _(" ...waiting for child to terminate.\n"));
|
||||
snprintf (kill_msg, sizeof kill_msg, _(" ...killed.\n"));
|
||||
snprintf (wait_msg, sizeof wait_msg, _(" ...waiting for child to terminate.\n"));
|
||||
|
||||
(void) signal (SIGALRM, kill_child);
|
||||
(void) signal (SIGCHLD, catch_signals);
|
||||
(void) alarm (2);
|
||||
|
||||
(void) wait (&status);
|
||||
sigemptyset (&ourset);
|
||||
if ((sigaddset (&ourset, SIGALRM) != 0)
|
||||
|| (sigprocmask (SIG_BLOCK, &ourset, NULL) != 0)) {
|
||||
fprintf (stderr, _("%s: signal masking malfunction\n"), Prog);
|
||||
kill_child (0);
|
||||
} else {
|
||||
while (0 == waitpid (pid_child, &status, WNOHANG)) {
|
||||
sigsuspend (&ourset);
|
||||
}
|
||||
pid_child = 0;
|
||||
(void) sigprocmask (SIG_UNBLOCK, &ourset, NULL);
|
||||
}
|
||||
|
||||
(void) fputs (_(" ...terminated.\n"), stderr);
|
||||
}
|
||||
|
||||
@@ -1076,6 +1107,21 @@ int main (int argc, char **argv)
|
||||
}
|
||||
#endif /* !USE_PAM */
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_fd = audit_open ();
|
||||
audit_log_acct_message (audit_fd,
|
||||
AUDIT_USER_ROLE_CHANGE,
|
||||
NULL, /* Prog. name */
|
||||
"su",
|
||||
('\0' != caller_name[0]) ? caller_name : "???",
|
||||
AUDIT_NO_ID,
|
||||
"localhost",
|
||||
NULL, /* addr */
|
||||
caller_tty,
|
||||
1); /* result */
|
||||
close (audit_fd);
|
||||
#endif /* WITH_AUDIT */
|
||||
|
||||
set_environment (pw);
|
||||
|
||||
if (!doshell) {
|
||||
|
||||
+71
-5
@@ -51,7 +51,9 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "chkname.h"
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
@@ -213,6 +215,7 @@ static void open_files (void);
|
||||
static void open_shadow (void);
|
||||
static void faillog_reset (uid_t);
|
||||
static void lastlog_reset (uid_t);
|
||||
static void tallylog_reset (char *);
|
||||
static void usr_update (void);
|
||||
static void create_home (void);
|
||||
static void create_mail (void);
|
||||
@@ -825,7 +828,7 @@ static void new_spent (struct spwd *spent)
|
||||
memzero (spent, sizeof *spent);
|
||||
spent->sp_namp = (char *) user_name;
|
||||
spent->sp_pwdp = (char *) user_pass;
|
||||
spent->sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent->sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent->sp_lstchg) {
|
||||
/* Better disable aging than requiring a password change */
|
||||
spent->sp_lstchg = -1;
|
||||
@@ -1789,6 +1792,52 @@ static void lastlog_reset (uid_t uid)
|
||||
}
|
||||
}
|
||||
|
||||
static void tallylog_reset (char *user_name)
|
||||
{
|
||||
const char pam_tally2[] = "/sbin/pam_tally2";
|
||||
const char *pname;
|
||||
pid_t childpid;
|
||||
int failed;
|
||||
int status;
|
||||
|
||||
if (access(pam_tally2, X_OK) == -1)
|
||||
return;
|
||||
|
||||
failed = 0;
|
||||
switch (childpid = fork())
|
||||
{
|
||||
case -1: /* error */
|
||||
failed = 1;
|
||||
break;
|
||||
case 0: /* child */
|
||||
pname = strrchr(pam_tally2, '/');
|
||||
if (pname == NULL)
|
||||
pname = pam_tally2;
|
||||
else
|
||||
pname++; /* Skip the '/' */
|
||||
execl(pam_tally2, pname, "--user", user_name, "--reset", "--quiet", NULL);
|
||||
/* If we come here, something has gone terribly wrong */
|
||||
perror(pam_tally2);
|
||||
exit(42); /* don't continue, we now have 2 processes running! */
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
default: /* parent */
|
||||
if (waitpid(childpid, &status, 0) == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (failed)
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("%s: failed to reset the tallylog entry of user \"%s\"\n"),
|
||||
Prog, user_name);
|
||||
SYSLOG ((LOG_WARN, "failed to reset the tallylog entry of user \"%s\"", user_name));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* usr_update - create the user entries
|
||||
*
|
||||
@@ -1896,6 +1945,9 @@ static void create_home (void)
|
||||
if (access (user_home, F_OK) != 0) {
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (user_home) != 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot set SELinux context for home directory %s\n"),
|
||||
Prog, user_home);
|
||||
fail_exit (E_HOMEDIR);
|
||||
}
|
||||
#endif
|
||||
@@ -1925,6 +1977,9 @@ static void create_home (void)
|
||||
#ifdef WITH_SELINUX
|
||||
/* Reset SELinux to create files with default contexts */
|
||||
if (reset_selinux_file_context () != 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot reset SELinux file creation context\n"),
|
||||
Prog);
|
||||
fail_exit (E_HOMEDIR);
|
||||
}
|
||||
#endif
|
||||
@@ -1994,8 +2049,8 @@ int main (int argc, char **argv)
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
uid_t uid_min = (uid_t) getdef_ulong ("UID_MIN", 1000UL);
|
||||
uid_t uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL);
|
||||
uid_t uid_min;
|
||||
uid_t uid_max;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2027,17 +2082,19 @@ int main (int argc, char **argv)
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
|
||||
get_defaults ();
|
||||
|
||||
process_flags (argc, argv);
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
uid_min = (uid_t) getdef_ulong ("UID_MIN", 1000UL);
|
||||
uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL);
|
||||
is_sub_uid = sub_uid_file_present () && !rflg &&
|
||||
(!user_id || (user_id <= uid_max && user_id >= uid_min));
|
||||
is_sub_gid = sub_gid_file_present () && !rflg &&
|
||||
(!user_id || (user_id <= uid_max && user_id >= uid_min));
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
|
||||
get_defaults ();
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
{
|
||||
@@ -2225,6 +2282,15 @@ int main (int argc, char **argv)
|
||||
|
||||
close_files ();
|
||||
|
||||
/*
|
||||
* tallylog_reset needs to be able to lookup
|
||||
* a valid existing user name,
|
||||
* so we canot call it before close_files()
|
||||
*/
|
||||
if (!lflg && getpwuid (user_id) != NULL) {
|
||||
tallylog_reset (user_name);
|
||||
}
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (Zflg) {
|
||||
if (set_seuser (user_name, user_selinux) != 0) {
|
||||
|
||||
+19
-4
@@ -641,7 +641,7 @@ static void new_spent (struct spwd *spent)
|
||||
spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp);
|
||||
|
||||
if (pflg) {
|
||||
spent->sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent->sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent->sp_lstchg) {
|
||||
/* Better disable aging than requiring a password
|
||||
* change. */
|
||||
@@ -1673,7 +1673,7 @@ static void usr_update (void)
|
||||
spent.sp_pwdp = xstrdup (pwent.pw_passwd);
|
||||
pwent.pw_passwd = xstrdup (SHADOW_PASSWD_STRING);
|
||||
|
||||
spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent.sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent.sp_lstchg) {
|
||||
/* Better disable aging than
|
||||
* requiring a password change */
|
||||
@@ -1756,6 +1756,14 @@ static void move_home (void)
|
||||
fail_exit (E_HOMEDIR);
|
||||
}
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
if (uflg || gflg) {
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing home directory owner",
|
||||
user_newname, (unsigned int) user_newid, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rename (user_home, user_newhome) == 0) {
|
||||
/* FIXME: rename above may have broken symlinks
|
||||
* pointing to the user's home directory
|
||||
@@ -2148,7 +2156,7 @@ int main (int argc, char **argv)
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_uid_add(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to add uid range %lu-%lu from '%s'\n"),
|
||||
_("%s: failed to add uid range %lu-%lu to '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_uid_dbname ());
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
@@ -2174,7 +2182,7 @@ int main (int argc, char **argv)
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_gid_add(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to add gid range %lu-%lu from '%s'\n"),
|
||||
_("%s: failed to add gid range %lu-%lu to '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_gid_dbname ());
|
||||
fail_exit (E_SUB_GID_UPDATE);
|
||||
@@ -2252,6 +2260,13 @@ int main (int argc, char **argv)
|
||||
* ownership.
|
||||
*
|
||||
*/
|
||||
#ifdef WITH_AUDIT
|
||||
if (uflg || gflg) {
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing home directory owner",
|
||||
user_newname, (unsigned int) user_newid, 1);
|
||||
}
|
||||
#endif
|
||||
if (chown_tree (dflg ? user_newhome : user_home,
|
||||
user_id,
|
||||
uflg ? user_newid : (uid_t)-1,
|
||||
|
||||
Reference in New Issue
Block a user