summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBalint Reczey <balint.reczey@canonical.com>2017-08-10 18:26:45 -0400
committerBalint Reczey <balint.reczey@canonical.com>2017-08-10 18:26:45 -0400
commit589f97ade4610b98cc532c8142343d4c33694e72 (patch)
tree38890f681daa26c57e865b4feca10d0ca53e1046 /src
parent365658d0f3a51814626afbb70aa2dd7b5e82ac36 (diff)
downloadshadow-589f97ade4610b98cc532c8142343d4c33694e72.tar.gz
New upstream version 4.5upstream/4.5
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am18
-rw-r--r--src/chpasswd.c2
-rw-r--r--src/newusers.c8
-rw-r--r--src/passwd.c2
-rw-r--r--src/su.c54
-rw-r--r--src/useradd.c76
-rw-r--r--src/usermod.c23
7 files changed, 155 insertions, 28 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index dc520b5d..12ef6308 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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
diff --git a/src/chpasswd.c b/src/chpasswd.c
index 21008f58..f9856726 100644
--- a/src/chpasswd.c
+++ b/src/chpasswd.c
@@ -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 */
diff --git a/src/newusers.c b/src/newusers.c
index 724cbb40..c38aec4b 100644
--- a/src/newusers.c
+++ b/src/newusers.c
@@ -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 ();
diff --git a/src/passwd.c b/src/passwd.c
index 1191111d..3af3e651 100644
--- a/src/passwd.c
+++ b/src/passwd.c
@@ -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 */
diff --git a/src/su.c b/src/su.c
index 93ffd2fb..974048e9 100644
--- a/src/su.c
+++ b/src/su.c
@@ -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) {
diff --git a/src/useradd.c b/src/useradd.c
index fefa234c..0e0fa1f8 100644
--- a/src/useradd.c
+++ b/src/useradd.c
@@ -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) {
diff --git a/src/usermod.c b/src/usermod.c
index 687487d9..9c5e479f 100644
--- a/src/usermod.c
+++ b/src/usermod.c
@@ -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,