mirror of
https://github.com/shadow-maint/shadow.git
synced 2026-01-29 23:34:11 +00:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08f27babeb | ||
|
|
ed61576cba | ||
|
|
0829017c4c | ||
|
|
b702d4c43f | ||
|
|
6f5a158b06 | ||
|
|
6be13b2f84 | ||
|
|
9a86c515a1 | ||
|
|
bce404a7a8 | ||
|
|
9b67543987 | ||
|
|
0e167e2a02 | ||
|
|
958b485999 | ||
|
|
a49d2acdb4 | ||
|
|
b43089bcf1 | ||
|
|
6cd3dcbbcc | ||
|
|
65668fe093 | ||
|
|
f4777ac542 | ||
|
|
976b7bffde | ||
|
|
c745eea4a4 | ||
|
|
f8732b17dd | ||
|
|
a472091869 | ||
|
|
d5638a5b2b | ||
|
|
ecaae2f8cd | ||
|
|
828f465cd2 | ||
|
|
eec97ce4c5 | ||
|
|
f051423a5a | ||
|
|
bd5fadaf29 | ||
|
|
268961e044 | ||
|
|
cb31772d7f | ||
|
|
67bcd85b77 | ||
|
|
2852d7aeed | ||
|
|
b42b1cc9b9 | ||
|
|
8800423a8a | ||
|
|
df90ed8a43 | ||
|
|
e37e43fd0a | ||
|
|
69a8862c27 | ||
|
|
a5b3d56e29 | ||
|
|
413c4908c8 | ||
|
|
78120f17df | ||
|
|
c8b7b5ef0d | ||
|
|
ddc2549f87 | ||
|
|
87ec7a52ab | ||
|
|
6d983709fa | ||
|
|
01f705ad50 | ||
|
|
3e8c105f07 | ||
|
|
a0d5a6165d | ||
|
|
ce9e598fac |
58
configure.ac
58
configure.ac
@ -123,18 +123,6 @@ AC_ARG_ENABLE([man],
|
||||
[enable_man="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE([account-tools-setuid],
|
||||
[AS_HELP_STRING([--enable-account-tools-setuid],
|
||||
[Install the user and group management tools setuid and authenticate the callers. This requires --with-libpam.])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_acct_tools_setuid="yes" ;;
|
||||
no) enable_acct_tools_setuid="no" ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-account-tools-setuid])
|
||||
;;
|
||||
esac],
|
||||
[enable_acct_tools_setuid="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE([subordinate-ids],
|
||||
[AS_HELP_STRING([--enable-subordinate-ids],
|
||||
[support subordinate ids @<:@default=yes@:>@])],
|
||||
@ -408,32 +396,6 @@ if test "$with_acl" != "no"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([LIBATTR])
|
||||
if test "$with_attr" != "no"; then
|
||||
AC_CHECK_HEADERS([attr/libattr.h attr/error_context.h], [attr_header="yes"], [attr_header="no"])
|
||||
if test "X$attr_header$with_attr" = "noyes" ; then
|
||||
AC_MSG_ERROR([attr/libattr.h or attr/error_context.h is missing])
|
||||
elif test "X$attr_header" = "Xyes" ; then
|
||||
AC_CHECK_LIB([attr], [attr_copy_file],
|
||||
[AC_CHECK_LIB([attr], [attr_copy_fd],
|
||||
[attr_lib="yes"],
|
||||
[attr_lib="no"])],
|
||||
[attr_lib="no"])
|
||||
if test "X$attr_lib$with_attr" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libattr not found])
|
||||
elif test "X$attr_lib" = "Xno" ; then
|
||||
with_attr="no"
|
||||
else
|
||||
AC_DEFINE([WITH_ATTR], [1],
|
||||
[Build shadow with Extended Attributes support])
|
||||
LIBATTR="-lattr"
|
||||
with_attr="yes"
|
||||
fi
|
||||
else
|
||||
with_attr="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([LIBAUDIT])
|
||||
if test "$with_audit" != "no"; then
|
||||
AC_CHECK_HEADER([libaudit.h], [audit_header="yes"], [audit_header="no"])
|
||||
@ -605,25 +567,6 @@ else
|
||||
fi
|
||||
AM_CONDITIONAL([USE_PAM], [test "X$with_libpam" = "Xyes"])
|
||||
|
||||
if test "$enable_acct_tools_setuid" != "no"; then
|
||||
if test "$with_libpam" != "yes"; then
|
||||
if test "X$enable_acct_tools_setuid" = "Xyes"; then
|
||||
AC_MSG_ERROR([PAM support is required for --enable-account-tools-setuid])
|
||||
else
|
||||
enable_acct_tools_setuid="no"
|
||||
fi
|
||||
else
|
||||
enable_acct_tools_setuid="yes"
|
||||
fi
|
||||
if test "X$enable_acct_tools_setuid" = "Xyes"; then
|
||||
AC_DEFINE([ACCT_TOOLS_SETUID],
|
||||
[1],
|
||||
[Define if account management tools should be installed setuid and authenticate the callers])
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([ACCT_TOOLS_SETUID], [test "x$enable_acct_tools_setuid" = "xyes"])
|
||||
|
||||
|
||||
AC_ARG_WITH([fcaps],
|
||||
[AS_HELP_STRING([--with-fcaps], [use file capabilities instead of suid binaries for newuidmap/newgidmap @<:@default=no@:>@])],
|
||||
[with_fcaps=$withval], [with_fcaps=no])
|
||||
@ -700,7 +643,6 @@ AC_MSG_NOTICE([shadow ${PACKAGE_VERSION} has been configured with the following
|
||||
|
||||
auditing support: $with_audit
|
||||
PAM support: $with_libpam
|
||||
suid account management tools: $enable_acct_tools_setuid
|
||||
SELinux support: $with_selinux
|
||||
BtrFS support: $with_btrfs
|
||||
ACL support: $with_acl
|
||||
|
||||
@ -10,25 +10,13 @@ pamd_files = \
|
||||
newusers \
|
||||
passwd
|
||||
|
||||
pamd_acct_tools_files = \
|
||||
chgpasswd \
|
||||
groupadd \
|
||||
groupdel \
|
||||
groupmod \
|
||||
useradd \
|
||||
userdel \
|
||||
usermod
|
||||
|
||||
if USE_PAM
|
||||
pamddir = $(sysconfdir)/pam.d
|
||||
pamd_DATA = $(pamd_files)
|
||||
if ACCT_TOOLS_SETUID
|
||||
pamd_DATA += $(pamd_acct_tools_files)
|
||||
endif
|
||||
endif
|
||||
|
||||
if WITH_SU
|
||||
pamd_files += su
|
||||
endif
|
||||
|
||||
EXTRA_DIST = $(pamd_files) $(pamd_acct_tools_files)
|
||||
EXTRA_DIST = $(pamd_files)
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
#%PAM-1.0
|
||||
auth sufficient pam_rootok.so
|
||||
account required pam_permit.so
|
||||
password include system-auth
|
||||
@ -1,4 +0,0 @@
|
||||
#%PAM-1.0
|
||||
auth sufficient pam_rootok.so
|
||||
account required pam_permit.so
|
||||
password include system-auth
|
||||
@ -1,4 +0,0 @@
|
||||
#%PAM-1.0
|
||||
auth sufficient pam_rootok.so
|
||||
account required pam_permit.so
|
||||
password include system-auth
|
||||
@ -1,4 +0,0 @@
|
||||
#%PAM-1.0
|
||||
auth sufficient pam_rootok.so
|
||||
account required pam_permit.so
|
||||
password include system-auth
|
||||
@ -1,4 +0,0 @@
|
||||
#%PAM-1.0
|
||||
auth sufficient pam_rootok.so
|
||||
account required pam_permit.so
|
||||
password include system-auth
|
||||
@ -1,4 +0,0 @@
|
||||
#%PAM-1.0
|
||||
auth sufficient pam_rootok.so
|
||||
account required pam_permit.so
|
||||
password include system-auth
|
||||
@ -1,4 +0,0 @@
|
||||
#%PAM-1.0
|
||||
auth sufficient pam_rootok.so
|
||||
account required pam_permit.so
|
||||
password include system-auth
|
||||
@ -179,7 +179,6 @@ libshadow_la_SOURCES = \
|
||||
shadowio.h \
|
||||
shadowlog.c \
|
||||
shadowlog.h \
|
||||
shadowlog_internal.h \
|
||||
shadowmem.c \
|
||||
shell.c \
|
||||
sizeof.h \
|
||||
|
||||
@ -37,7 +37,6 @@ int
|
||||
add_groups(const char *list)
|
||||
{
|
||||
char *dup;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
gid_t *gids;
|
||||
size_t n;
|
||||
|
||||
@ -62,7 +61,7 @@ add_groups(const char *list)
|
||||
|
||||
grp = getgrnam(g); /* local, no need for xgetgrnam */
|
||||
if (NULL == grp) {
|
||||
fprintf(shadow_logfd, _("Warning: unknown group %s\n"), g);
|
||||
fprintf(log_get_logfd(), _("Warning: unknown group %s\n"), g);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -72,7 +71,7 @@ add_groups(const char *list)
|
||||
free(dup);
|
||||
|
||||
if (setgroups(n, gids) == -1) {
|
||||
fprintf(shadow_logfd, "setgroups: %s\n", strerrno());
|
||||
fprintf(log_get_logfd(), "setgroups: %s\n", strerrno());
|
||||
goto free_gids;
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
|
||||
|
||||
/*
|
||||
* match_regex - return true if match, false if not
|
||||
@ -28,15 +31,24 @@ match_regex(const char *pattern, const char *string)
|
||||
|
||||
|
||||
/*
|
||||
* is_valid_hash - check if the given string is a valid password hash
|
||||
*
|
||||
* Returns true if the string appears to be a valid hash, false otherwise.
|
||||
* is_valid_hash - check if the string is a valid shadow(5) 2nd field.
|
||||
*
|
||||
* regex from: https://man.archlinux.org/man/crypt.5.en
|
||||
*/
|
||||
bool
|
||||
is_valid_hash(const char *hash)
|
||||
{
|
||||
// Password temporarily locked
|
||||
hash = strprefix(hash, "!") ?: hash;
|
||||
|
||||
// Passwordless account; discouraged
|
||||
if (streq(hash, ""))
|
||||
return true;
|
||||
|
||||
// Password permanently locked (and forgotten)
|
||||
if (streq(hash, "*"))
|
||||
return true;
|
||||
|
||||
// Minimum hash length
|
||||
if (strlen(hash) < 13)
|
||||
return false;
|
||||
@ -50,15 +62,15 @@ is_valid_hash(const char *hash)
|
||||
return true;
|
||||
|
||||
// SHA-512: $6$ + salt + $ + 86-char hash
|
||||
if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash))
|
||||
if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash))
|
||||
return true;
|
||||
|
||||
// SHA-256: $5$ + salt + $ + 43-char hash
|
||||
if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash))
|
||||
if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash))
|
||||
return true;
|
||||
|
||||
// MD5: $1$ + salt + $ + 22-char hash
|
||||
if (match_regex("^\\$1\\$[^$:\\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash))
|
||||
if (match_regex("^\\$1\\$[^$:\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash))
|
||||
return true;
|
||||
|
||||
// DES: exactly 13 characters from [A-Za-z0-9./]
|
||||
|
||||
@ -53,9 +53,8 @@ void chown_tty (const struct passwd *info)
|
||||
if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0)
|
||||
|| (fchmod (STDIN_FILENO, getdef_num ("TTYPERM", 0600)) != 0)) {
|
||||
int err = errno;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Unable to change owner or mode of tty stdin: %s"),
|
||||
strerror (err));
|
||||
SYSLOG ((LOG_WARN,
|
||||
|
||||
141
lib/commonio.c
141
lib/commonio.c
@ -27,12 +27,13 @@
|
||||
#include "atoi/getnum.h"
|
||||
#include "commonio.h"
|
||||
#include "defines.h"
|
||||
#include "fs/mkstemp/fmkomstemp.h"
|
||||
#include "nscd.h"
|
||||
#ifdef WITH_TCB
|
||||
#include <tcb.h>
|
||||
#endif /* WITH_TCB */
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "sssd.h"
|
||||
#include "string/memset/memzero.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
@ -44,12 +45,10 @@
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
static int lrename (const char *, const char *);
|
||||
static int check_link_count (const char *file, bool log);
|
||||
static int do_lock_file (const char *file, const char *lock, bool log);
|
||||
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
|
||||
const char *name,
|
||||
const char *mode,
|
||||
static /*@null@*/ /*@dependent@*/FILE *fmkstemp_set_perms (
|
||||
char *name,
|
||||
const struct stat *sb);
|
||||
static int create_backup (const char *, FILE *);
|
||||
static void free_linked_list (struct commonio_db *);
|
||||
@ -69,50 +68,24 @@ static /*@dependent@*/ /*@null@*/struct commonio_entry *next_entry_by_name (
|
||||
static int lock_count = 0;
|
||||
static bool nscd_need_reload = false;
|
||||
|
||||
/*
|
||||
* Simple rename(P) alternative that attempts to rename to symlink
|
||||
* target.
|
||||
*/
|
||||
int lrename (const char *old, const char *new)
|
||||
{
|
||||
int res;
|
||||
char *r = NULL;
|
||||
struct stat sb;
|
||||
|
||||
if (lstat (new, &sb) == 0 && S_ISLNK (sb.st_mode)) {
|
||||
r = realpath (new, NULL);
|
||||
if (NULL == r) {
|
||||
perror ("realpath in lrename()");
|
||||
} else {
|
||||
new = r;
|
||||
}
|
||||
}
|
||||
|
||||
res = rename (old, new);
|
||||
|
||||
free (r);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int check_link_count (const char *file, bool log)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (stat (file, &sb) != 0) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: %s file stat error: %s\n",
|
||||
shadow_progname, file, strerrno());
|
||||
log_get_progname(), file, strerrno());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sb.st_nlink != 2) {
|
||||
if (log) {
|
||||
fprintf(shadow_logfd,
|
||||
fprintf(log_get_logfd(),
|
||||
"%s: %s: lock file already used (nlink: %ju)\n",
|
||||
shadow_progname, file, (uintmax_t) sb.st_nlink);
|
||||
log_get_progname(), file, (uintmax_t) sb.st_nlink);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -132,9 +105,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||
if (-1 == fd) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: %s: %s\n",
|
||||
shadow_progname, file, strerrno());
|
||||
log_get_progname(), file, strerrno());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -144,9 +117,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
len = (ssize_t) strlen (buf) + 1;
|
||||
if (write_full(fd, buf, len) == -1) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: %s file write error: %s\n",
|
||||
shadow_progname, file, strerrno());
|
||||
log_get_progname(), file, strerrno());
|
||||
}
|
||||
(void) close (fd);
|
||||
unlink (file);
|
||||
@ -154,9 +127,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
}
|
||||
if (fdatasync (fd) == -1) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: %s file sync error: %s\n",
|
||||
shadow_progname, file, strerrno());
|
||||
log_get_progname(), file, strerrno());
|
||||
}
|
||||
(void) close (fd);
|
||||
unlink (file);
|
||||
@ -173,9 +146,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
fd = open (lock, O_RDWR);
|
||||
if (-1 == fd) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: %s: %s\n",
|
||||
shadow_progname, lock, strerrno());
|
||||
log_get_progname(), lock, strerrno());
|
||||
}
|
||||
unlink (file);
|
||||
errno = EINVAL;
|
||||
@ -185,9 +158,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
close (fd);
|
||||
if (len <= 0) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: existing lock file %s without a PID\n",
|
||||
shadow_progname, lock);
|
||||
log_get_progname(), lock);
|
||||
}
|
||||
unlink (file);
|
||||
errno = EINVAL;
|
||||
@ -196,9 +169,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
stpcpy(&buf[len], "");
|
||||
if (get_pid(buf, &pid) == -1) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: existing lock file %s with an invalid PID '%s'\n",
|
||||
shadow_progname, lock, buf);
|
||||
log_get_progname(), lock, buf);
|
||||
}
|
||||
unlink (file);
|
||||
errno = EINVAL;
|
||||
@ -206,9 +179,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
}
|
||||
if (kill (pid, 0) == 0) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: lock %s already used by PID %lu\n",
|
||||
shadow_progname, lock, (unsigned long) pid);
|
||||
log_get_progname(), lock, (unsigned long) pid);
|
||||
}
|
||||
unlink (file);
|
||||
errno = EEXIST;
|
||||
@ -216,9 +189,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
}
|
||||
if (unlink (lock) != 0) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: cannot get lock %s: %s\n",
|
||||
shadow_progname, lock, strerrno());
|
||||
log_get_progname(), lock, strerrno());
|
||||
}
|
||||
unlink (file);
|
||||
return 0;
|
||||
@ -229,9 +202,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
retval = check_link_count (file, log);
|
||||
} else {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: cannot get lock %s: %s\n",
|
||||
shadow_progname, lock, strerrno());
|
||||
log_get_progname(), lock, strerrno());
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,17 +213,13 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
}
|
||||
|
||||
|
||||
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
|
||||
const char *name,
|
||||
const char *mode,
|
||||
static /*@null@*/ /*@dependent@*/FILE *fmkstemp_set_perms (
|
||||
char *name,
|
||||
const struct stat *sb)
|
||||
{
|
||||
FILE *fp;
|
||||
mode_t mask;
|
||||
|
||||
mask = umask (0777);
|
||||
fp = fopen (name, mode);
|
||||
(void) umask (mask);
|
||||
fp = fmkomstemp(name, 0, 0600);
|
||||
if (NULL == fp) {
|
||||
return NULL;
|
||||
}
|
||||
@ -266,24 +235,26 @@ static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
|
||||
|
||||
fail:
|
||||
(void) fclose (fp);
|
||||
/* fopen_set_perms is used for intermediate files */
|
||||
/* fmkstemp_set_perms is used for intermediate files */
|
||||
(void) unlink (name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int create_backup (const char *backup, FILE * fp)
|
||||
static int create_backup (const char *name, FILE * fp)
|
||||
{
|
||||
char tmpf[PATH_MAX], target[PATH_MAX];
|
||||
struct stat sb;
|
||||
struct utimbuf ub;
|
||||
FILE *bkfp;
|
||||
int c;
|
||||
|
||||
stprintf_a(tmpf, "%s.cioXXXXXX", name);
|
||||
if (fstat (fileno (fp), &sb) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bkfp = fopen_set_perms (backup, "w", &sb);
|
||||
bkfp = fmkstemp_set_perms(tmpf, &sb);
|
||||
if (NULL == bkfp) {
|
||||
return -1;
|
||||
}
|
||||
@ -299,22 +270,28 @@ static int create_backup (const char *backup, FILE * fp)
|
||||
}
|
||||
if ((c != EOF) || (ferror (fp) != 0) || (fflush (bkfp) != 0)) {
|
||||
(void) fclose (bkfp);
|
||||
/* FIXME: unlink the backup file? */
|
||||
unlink(tmpf);
|
||||
return -1;
|
||||
}
|
||||
if (fsync (fileno (bkfp)) != 0) {
|
||||
(void) fclose (bkfp);
|
||||
/* FIXME: unlink the backup file? */
|
||||
unlink(tmpf);
|
||||
return -1;
|
||||
}
|
||||
if (fclose (bkfp) != 0) {
|
||||
/* FIXME: unlink the backup file? */
|
||||
unlink(tmpf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
stprintf_a(target, "%s-", name);
|
||||
if (rename(tmpf, target) != 0) {
|
||||
unlink(tmpf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ub.actime = sb.st_atime;
|
||||
ub.modtime = sb.st_mtime;
|
||||
(void) utime (backup, &ub);
|
||||
(void) utime(target, &ub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -402,9 +379,9 @@ int commonio_lock (struct commonio_db *db)
|
||||
if (0 == lock_count) {
|
||||
if (lckpwdf () == -1) {
|
||||
if (geteuid () != 0) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
"%s: Permission denied.\n",
|
||||
shadow_progname);
|
||||
log_get_progname());
|
||||
}
|
||||
return 0; /* failure */
|
||||
}
|
||||
@ -438,8 +415,8 @@ int commonio_lock (struct commonio_db *db)
|
||||
}
|
||||
/* no unnecessary retries on "permission denied" errors */
|
||||
if (geteuid () != 0) {
|
||||
(void) fprintf (shadow_logfd, "%s: Permission denied.\n",
|
||||
shadow_progname);
|
||||
(void) fprintf (log_get_logfd(), "%s: Permission denied.\n",
|
||||
log_get_progname());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -868,7 +845,7 @@ int
|
||||
commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
|
||||
{
|
||||
bool errors = false;
|
||||
char buf[1024];
|
||||
char tmpf[PATH_MAX];
|
||||
struct stat sb;
|
||||
|
||||
if (!db->isopen) {
|
||||
@ -900,19 +877,13 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
|
||||
/*
|
||||
* Create backup file.
|
||||
*/
|
||||
if (stprintf_a(buf, "%s-", db->filename) == -1) {
|
||||
(void) fclose (db->fp);
|
||||
db->fp = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (process_selinux
|
||||
&& set_selinux_file_context (db->filename, S_IFREG) != 0) {
|
||||
errors = true;
|
||||
}
|
||||
#endif
|
||||
if (create_backup (buf, db->fp) != 0) {
|
||||
if (create_backup(db->filename, db->fp) != 0) {
|
||||
errors = true;
|
||||
}
|
||||
|
||||
@ -939,7 +910,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
|
||||
sb.st_gid = db->st_gid;
|
||||
}
|
||||
|
||||
if (stprintf_a(buf, "%s+", db->filename) == -1)
|
||||
if (stprintf_a(tmpf, "%s.cioXXXXXX", db->filename) == -1)
|
||||
goto fail;
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
@ -949,7 +920,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
|
||||
}
|
||||
#endif
|
||||
|
||||
db->fp = fopen_set_perms (buf, "w", &sb);
|
||||
db->fp = fmkstemp_set_perms(tmpf, &sb);
|
||||
if (NULL == db->fp) {
|
||||
goto fail;
|
||||
}
|
||||
@ -973,11 +944,11 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
|
||||
db->fp = NULL;
|
||||
|
||||
if (errors) {
|
||||
unlink (buf);
|
||||
unlink(tmpf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (lrename (buf, db->filename) != 0) {
|
||||
if (rename(tmpf, db->filename) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1045,7 +1016,7 @@ int commonio_update (struct commonio_db *db, const void *eptr)
|
||||
p = find_entry_by_name(db, db->ops->cio_getname(eptr));
|
||||
if (NULL != p) {
|
||||
if (next_entry_by_name(db, p->next, db->ops->cio_getname(eptr)) != NULL) {
|
||||
fprintf(shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->cio_getname(eptr), db->filename);
|
||||
fprintf(log_get_logfd(), _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->cio_getname(eptr), db->filename);
|
||||
db->ops->cio_free(nentry);
|
||||
return 0;
|
||||
}
|
||||
@ -1150,7 +1121,7 @@ int commonio_remove (struct commonio_db *db, const char *name)
|
||||
return 0;
|
||||
}
|
||||
if (next_entry_by_name (db, p->next, name) != NULL) {
|
||||
fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename);
|
||||
fprintf (log_get_logfd(), _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
117
lib/copydir.c
117
lib/copydir.c
@ -27,16 +27,11 @@
|
||||
#ifdef WITH_SELINUX
|
||||
#include <selinux/selinux.h>
|
||||
#endif /* WITH_SELINUX */
|
||||
#if defined(WITH_ACL) || defined(WITH_ATTR)
|
||||
#if defined(WITH_ACL)
|
||||
#include <stdarg.h>
|
||||
#include <attr/error_context.h>
|
||||
#endif /* WITH_ACL || WITH_ATTR */
|
||||
#ifdef WITH_ACL
|
||||
#include <acl/libacl.h>
|
||||
#endif /* WITH_ACL */
|
||||
#ifdef WITH_ATTR
|
||||
#include <attr/libattr.h>
|
||||
#endif /* WITH_ATTR */
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
@ -63,11 +58,9 @@ struct path_info {
|
||||
};
|
||||
|
||||
static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
@ -78,12 +71,10 @@ static int copy_symlink (const struct path_info *src, const struct path_info *ds
|
||||
static int copy_hardlink (const struct path_info *dst,
|
||||
struct link_name *lp);
|
||||
static int copy_special (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static int copy_file (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
@ -94,7 +85,7 @@ static int fchown_if_needed (int fdst, const struct stat *statp,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
|
||||
#if defined(WITH_ACL) || defined(WITH_ATTR)
|
||||
#if defined(WITH_ACL)
|
||||
/*
|
||||
* error_acl - format the error messages for the ACL and EQ libraries.
|
||||
*/
|
||||
@ -103,7 +94,6 @@ static void
|
||||
error_acl(struct error_context *, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
|
||||
/* ignore the case when destination does not support ACLs
|
||||
* or extended attributes */
|
||||
@ -113,18 +103,18 @@ error_acl(struct error_context *, const char *fmt, ...)
|
||||
}
|
||||
|
||||
va_start (ap, fmt);
|
||||
(void) fprintf (shadow_logfd, _("%s: "), log_get_progname());
|
||||
if (vfprintf (shadow_logfd, fmt, ap) != 0) {
|
||||
(void) fputs (_(": "), shadow_logfd);
|
||||
(void) fprintf (log_get_logfd(), _("%s: "), log_get_progname());
|
||||
if (vfprintf (log_get_logfd(), fmt, ap) != 0) {
|
||||
(void) fputs (_(": "), log_get_logfd());
|
||||
}
|
||||
(void) fprintf(shadow_logfd, "%s\n", strerrno());
|
||||
(void) fprintf(log_get_logfd(), "%s\n", strerrno());
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
static struct error_context ctx = {
|
||||
error_acl, NULL, NULL
|
||||
};
|
||||
#endif /* WITH_ACL || WITH_ATTR */
|
||||
#endif /* WITH_ACL */
|
||||
|
||||
#ifdef WITH_ACL
|
||||
static int perm_copy_path(const struct path_info *src,
|
||||
@ -151,32 +141,6 @@ static int perm_copy_path(const struct path_info *src,
|
||||
}
|
||||
#endif /* WITH_ACL */
|
||||
|
||||
#ifdef WITH_ATTR
|
||||
static int attr_copy_path(const struct path_info *src,
|
||||
const struct path_info *dst,
|
||||
int (*callback) (const char *, struct error_context *),
|
||||
struct error_context *errctx)
|
||||
{
|
||||
int src_fd, dst_fd, ret;
|
||||
|
||||
src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
|
||||
if (src_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
|
||||
if (dst_fd < 0) {
|
||||
(void) close (src_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = attr_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, callback, errctx);
|
||||
(void) close (src_fd);
|
||||
(void) close (dst_fd);
|
||||
return ret;
|
||||
}
|
||||
#endif /* WITH_ATTR */
|
||||
|
||||
/*
|
||||
* remove_link - delete a link from the linked list
|
||||
*/
|
||||
@ -241,7 +205,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
|
||||
}
|
||||
|
||||
static int copy_tree_impl (const struct path_info *src, const struct path_info *dst,
|
||||
bool copy_root, bool reset_selinux,
|
||||
bool copy_root,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
@ -269,8 +233,7 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
|
||||
return -1;
|
||||
}
|
||||
|
||||
return copy_entry (src, dst, reset_selinux,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
return copy_entry (src, dst, old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -341,7 +304,7 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
|
||||
dst_entry.dirfd = dst_fd;
|
||||
dst_entry.name = ent->d_name;
|
||||
|
||||
err = copy_entry(&src_entry, &dst_entry, reset_selinux,
|
||||
err = copy_entry(&src_entry, &dst_entry,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
|
||||
free(dst_name);
|
||||
@ -397,7 +360,6 @@ skip:
|
||||
* to -1.
|
||||
*/
|
||||
static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
@ -419,7 +381,7 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
mt[1].tv_nsec = sb.st_mtim.tv_nsec;
|
||||
|
||||
if (S_ISDIR (sb.st_mode)) {
|
||||
err = copy_dir (src, dst, reset_selinux, &sb, mt,
|
||||
err = copy_dir (src, dst, &sb, mt,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
|
||||
@ -455,7 +417,7 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
*/
|
||||
|
||||
else if (!S_ISREG (sb.st_mode)) {
|
||||
err = copy_special (src, dst, reset_selinux, &sb, mt,
|
||||
err = copy_special (src, dst, &sb, mt,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
|
||||
@ -465,7 +427,7 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
*/
|
||||
|
||||
else {
|
||||
err = copy_file (src, dst, reset_selinux, &sb, mt,
|
||||
err = copy_file (src, dst, &sb, mt,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
|
||||
@ -483,7 +445,6 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
@ -506,7 +467,7 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
* but copy into it (recursively).
|
||||
*/
|
||||
if (fstatat(dst->dirfd, dst->name, &dst_sb, AT_SYMLINK_NOFOLLOW) == 0 && S_ISDIR(dst_sb.st_mode)) {
|
||||
return (copy_tree_impl (src, dst, false, reset_selinux,
|
||||
return (copy_tree_impl (src, dst, false,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0);
|
||||
}
|
||||
|
||||
@ -518,19 +479,7 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
|| ( (perm_copy_path (src, dst, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#endif /* WITH_ACL */
|
||||
#ifdef WITH_ATTR
|
||||
/*
|
||||
* If the third parameter is NULL, all extended attributes
|
||||
* except those that define Access Control Lists are copied.
|
||||
* ACLs are excluded by default because copying them between
|
||||
* file systems with and without ACL support needs some
|
||||
* additional logic so that no unexpected permissions result.
|
||||
*/
|
||||
|| ( !reset_selinux
|
||||
&& (attr_copy_path (src, dst, NULL, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#endif /* WITH_ATTR */
|
||||
|| (copy_tree_impl (src, dst, false, reset_selinux,
|
||||
|| (copy_tree_impl (src, dst, false,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0)
|
||||
|| (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) {
|
||||
err = -1;
|
||||
@ -651,7 +600,6 @@ static int copy_hardlink (const struct path_info *dst,
|
||||
*/
|
||||
static int
|
||||
copy_special(MAYBE_UNUSED const struct path_info *src, const struct path_info *dst,
|
||||
MAYBE_UNUSED bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
@ -675,20 +623,6 @@ copy_special(MAYBE_UNUSED const struct path_info *src, const struct path_info *d
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#if defined(WITH_ATTR)
|
||||
/*
|
||||
* If the third parameter is NULL, all extended attributes
|
||||
* except those that define Access Control Lists are copied.
|
||||
* ACLs are excluded by default because copying them between
|
||||
* file systems with and without ACL support needs some
|
||||
* additional logic so that no unexpected permissions result.
|
||||
*/
|
||||
if (!reset_selinux) {
|
||||
if (attr_copy_path(src, dst, NULL, &ctx) == -1 && errno != 0)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (utimensat(dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) == -1)
|
||||
return -1;
|
||||
|
||||
@ -706,7 +640,6 @@ copy_special(MAYBE_UNUSED const struct path_info *src, const struct path_info *d
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_file (const struct path_info *src, const struct path_info *dst,
|
||||
MAYBE_UNUSED bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
@ -734,18 +667,6 @@ static int copy_file (const struct path_info *src, const struct path_info *dst,
|
||||
|| ( (perm_copy_fd (src->full_path, ifd, dst->full_path, ofd, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#endif /* WITH_ACL */
|
||||
#ifdef WITH_ATTR
|
||||
/*
|
||||
* If the third parameter is NULL, all extended attributes
|
||||
* except those that define Access Control Lists are copied.
|
||||
* ACLs are excluded by default because copying them between
|
||||
* file systems with and without ACL support needs some
|
||||
* additional logic so that no unexpected permissions result.
|
||||
*/
|
||||
|| ( !reset_selinux
|
||||
&& (attr_copy_fd (src->full_path, ifd, dst->full_path, ofd, NULL, &ctx) != 0)
|
||||
&& (errno != 0))
|
||||
#endif /* WITH_ATTR */
|
||||
) {
|
||||
if (ofd >= 0) {
|
||||
(void) close (ofd);
|
||||
@ -857,9 +778,6 @@ static int chownat_if_needed (const struct path_info *dst,
|
||||
* copy_tree() walks a directory tree and copies ordinary files
|
||||
* as it goes.
|
||||
*
|
||||
* When reset_selinux is enabled, extended attributes (and thus
|
||||
* SELinux attributes) are not copied.
|
||||
*
|
||||
* old_uid and new_uid are used to set the ownership of the copied
|
||||
* files. Unless old_uid is set to -1, only the files owned by
|
||||
* old_uid have their ownership changed to new_uid. In addition, if
|
||||
@ -869,7 +787,7 @@ static int chownat_if_needed (const struct path_info *dst,
|
||||
* old_gid/new_gid.
|
||||
*/
|
||||
int copy_tree (const char *src_root, const char *dst_root,
|
||||
bool copy_root, bool reset_selinux,
|
||||
bool copy_root,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
@ -884,6 +802,5 @@ int copy_tree (const char *src_root, const char *dst_root,
|
||||
.name = dst_root
|
||||
};
|
||||
|
||||
return copy_tree_impl(&src, &dst, copy_root, reset_selinux,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
return copy_tree_impl(&src, &dst, copy_root, old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
method = &nummethod[0];
|
||||
}
|
||||
}
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("crypt method not supported by libcrypt? (%s)\n"),
|
||||
method);
|
||||
errno = EINVAL;
|
||||
|
||||
14
lib/getdef.c
14
lib/getdef.c
@ -26,7 +26,7 @@
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "sizeof.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/strcmp/strcaseeq.h"
|
||||
@ -255,7 +255,7 @@ getdef_num(const char *item, int dflt)
|
||||
}
|
||||
|
||||
if (a2si(&val, d->value, NULL, 0, -1, INT_MAX) == -1) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("configuration error - cannot parse %s value: '%s'"),
|
||||
item, d->value);
|
||||
return dflt;
|
||||
@ -289,7 +289,7 @@ getdef_unum(const char *item, unsigned int dflt)
|
||||
}
|
||||
|
||||
if (a2ui(&val, d->value, NULL, 0, 0, UINT_MAX) == -1) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("configuration error - cannot parse %s value: '%s'"),
|
||||
item, d->value);
|
||||
return dflt;
|
||||
@ -322,7 +322,7 @@ long getdef_long (const char *item, long dflt)
|
||||
}
|
||||
|
||||
if (a2sl(&val, d->value, NULL, 0, -1, LONG_MAX) == -1) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("configuration error - cannot parse %s value: '%s'"),
|
||||
item, d->value);
|
||||
return dflt;
|
||||
@ -354,7 +354,7 @@ unsigned long getdef_ulong (const char *item, unsigned long dflt)
|
||||
}
|
||||
|
||||
if (str2ul(&val, d->value) == -1) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("configuration error - cannot parse %s value: '%s'"),
|
||||
item, d->value);
|
||||
return dflt;
|
||||
@ -391,7 +391,7 @@ int putdef_str (const char *name, const char *value, const char *srcfile)
|
||||
cp = strdup (value);
|
||||
if (NULL == cp) {
|
||||
(void) fputs (_("Could not allocate space for config info.\n"),
|
||||
shadow_logfd);
|
||||
log_get_logfd());
|
||||
SYSLOG ((LOG_ERR, "could not allocate space for config info"));
|
||||
return -1;
|
||||
}
|
||||
@ -435,7 +435,7 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name, cons
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("configuration error - unknown item '%s' (notify administrator)\n"),
|
||||
name);
|
||||
if (srcfile != NULL)
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
gettime(void)
|
||||
{
|
||||
char *source_date_epoch;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
time_t fallback, epoch;
|
||||
|
||||
fallback = time (NULL);
|
||||
@ -39,7 +38,7 @@ gettime(void)
|
||||
return fallback;
|
||||
|
||||
if (a2i(time_t, &epoch, source_date_epoch, NULL, 10, 0, fallback) == -1) {
|
||||
fprintf(shadow_logfd,
|
||||
fprintf(log_get_logfd(),
|
||||
_("Environment variable $SOURCE_DATE_EPOCH: a2i(\"%s\"): %s"),
|
||||
source_date_epoch, strerrno());
|
||||
return fallback;
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
|
||||
14
lib/nscd.c
14
lib/nscd.c
@ -10,7 +10,7 @@
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "nscd.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
#define MSG_NSCD_FLUSH_CACHE_FAILED "%s: Failed to flush the nscd cache.\n"
|
||||
|
||||
@ -26,15 +26,15 @@ int nscd_flush_cache (const char *service)
|
||||
|
||||
if (run_command (cmd, spawnedArgs, spawnedEnv, &status) != 0) {
|
||||
/* run_command writes its own more detailed message. */
|
||||
(void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), shadow_progname);
|
||||
(void) fprintf (log_get_logfd(), _(MSG_NSCD_FLUSH_CACHE_FAILED), log_get_progname());
|
||||
return -1;
|
||||
}
|
||||
|
||||
code = WEXITSTATUS (status);
|
||||
if (!WIFEXITED (status)) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: nscd did not terminate normally (signal %d)\n"),
|
||||
shadow_progname, WTERMSIG (status));
|
||||
log_get_progname(), WTERMSIG (status));
|
||||
return -1;
|
||||
} else if (code == E_CMD_NOTFOUND) {
|
||||
/* nscd is not installed, or it is installed but uses an
|
||||
@ -44,9 +44,9 @@ int nscd_flush_cache (const char *service)
|
||||
/* nscd is installed, but it isn't active. */
|
||||
return 0;
|
||||
} else if (code != 0) {
|
||||
(void) fprintf (shadow_logfd, _("%s: nscd exited with status %d\n"),
|
||||
shadow_progname, code);
|
||||
(void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), shadow_progname);
|
||||
(void) fprintf (log_get_logfd(), _("%s: nscd exited with status %d\n"),
|
||||
log_get_progname(), code);
|
||||
(void) fprintf (log_get_logfd(), _(MSG_NSCD_FLUSH_CACHE_FAILED), log_get_progname());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
22
lib/nss.c
22
lib/nss.c
@ -12,7 +12,6 @@
|
||||
#include "alloc/malloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "../libsubid/subid.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
#include "string/strcmp/strcaseprefix.h"
|
||||
@ -55,7 +54,6 @@ nss_init(const char *nsswitch_path) {
|
||||
char *line = NULL, *p;
|
||||
char libname[64];
|
||||
FILE *nssfp = NULL;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
void *h;
|
||||
size_t len = 0;
|
||||
|
||||
@ -74,7 +72,7 @@ nss_init(const char *nsswitch_path) {
|
||||
nssfp = fopen(nsswitch_path, "r");
|
||||
if (!nssfp) {
|
||||
if (errno != ENOENT)
|
||||
fprintf(shadow_logfd, "Failed opening %s: %m\n", nsswitch_path);
|
||||
fprintf(log_get_logfd(), "Failed opening %s: %m\n", nsswitch_path);
|
||||
|
||||
atomic_store(&nss_init_completed, true);
|
||||
return;
|
||||
@ -97,7 +95,7 @@ nss_init(const char *nsswitch_path) {
|
||||
goto null_subid;
|
||||
}
|
||||
if (stpsep(p, " \t\n") == NULL) {
|
||||
fprintf(shadow_logfd, "No usable subid NSS module found, using files\n");
|
||||
fprintf(log_get_logfd(), "No usable subid NSS module found, using files\n");
|
||||
// subid_nss has to be null here, but to ease reviews:
|
||||
goto null_subid;
|
||||
}
|
||||
@ -105,15 +103,15 @@ nss_init(const char *nsswitch_path) {
|
||||
goto null_subid;
|
||||
}
|
||||
if (strlen(p) > 50) {
|
||||
fprintf(shadow_logfd, "Subid NSS module name too long (longer than 50 characters): %s\n", p);
|
||||
fprintf(shadow_logfd, "Using files\n");
|
||||
fprintf(log_get_logfd(), "Subid NSS module name too long (longer than 50 characters): %s\n", p);
|
||||
fprintf(log_get_logfd(), "Using files\n");
|
||||
goto null_subid;
|
||||
}
|
||||
stprintf_a(libname, "libsubid_%s.so", p);
|
||||
h = dlopen(libname, RTLD_LAZY);
|
||||
if (!h) {
|
||||
fprintf(shadow_logfd, "Error opening %s: %s\n", libname, dlerror());
|
||||
fprintf(shadow_logfd, "Using files\n");
|
||||
fprintf(log_get_logfd(), "Error opening %s: %s\n", libname, dlerror());
|
||||
fprintf(log_get_logfd(), "Using files\n");
|
||||
goto null_subid;
|
||||
}
|
||||
subid_nss = malloc_T(1, struct subid_nss_ops);
|
||||
@ -122,22 +120,22 @@ nss_init(const char *nsswitch_path) {
|
||||
}
|
||||
subid_nss->has_range = dlsym(h, "shadow_subid_has_range");
|
||||
if (!subid_nss->has_range) {
|
||||
fprintf(shadow_logfd, "%s did not provide @has_range@\n", libname);
|
||||
fprintf(log_get_logfd(), "%s did not provide @has_range@\n", libname);
|
||||
goto close_lib;
|
||||
}
|
||||
subid_nss->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges");
|
||||
if (!subid_nss->list_owner_ranges) {
|
||||
fprintf(shadow_logfd, "%s did not provide @list_owner_ranges@\n", libname);
|
||||
fprintf(log_get_logfd(), "%s did not provide @list_owner_ranges@\n", libname);
|
||||
goto close_lib;
|
||||
}
|
||||
subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners");
|
||||
if (!subid_nss->find_subid_owners) {
|
||||
fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
|
||||
fprintf(log_get_logfd(), "%s did not provide @find_subid_owners@\n", libname);
|
||||
goto close_lib;
|
||||
}
|
||||
subid_nss->free = dlsym(h, "shadow_subid_free");
|
||||
if (!subid_nss->free) {
|
||||
fprintf(shadow_logfd, "%s did not provide @subid_free@\n", libname);
|
||||
fprintf(log_get_logfd(), "%s did not provide @subid_free@\n", libname);
|
||||
goto close_lib;
|
||||
}
|
||||
subid_nss->handle = h;
|
||||
|
||||
@ -32,7 +32,6 @@ void do_pam_passwd (const char *user, bool silent, bool change_expired)
|
||||
{
|
||||
pam_handle_t *pamh = NULL;
|
||||
int flags = 0, ret;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
|
||||
if (silent)
|
||||
flags |= PAM_SILENT;
|
||||
@ -41,20 +40,20 @@ void do_pam_passwd (const char *user, bool silent, bool change_expired)
|
||||
|
||||
ret = pam_start ("passwd", user, &conv, &pamh);
|
||||
if (ret != PAM_SUCCESS) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("passwd: pam_start() failed, error %d\n"), ret);
|
||||
exit (E_PAM_ERR);
|
||||
}
|
||||
|
||||
ret = pam_chauthtok (pamh, flags);
|
||||
if (ret != PAM_SUCCESS) {
|
||||
fprintf (shadow_logfd, _("passwd: %s\n"), pam_strerror (pamh, ret));
|
||||
fputs (_("passwd: password unchanged\n"), shadow_logfd);
|
||||
fprintf (log_get_logfd(), _("passwd: %s\n"), pam_strerror (pamh, ret));
|
||||
fputs (_("passwd: password unchanged\n"), log_get_logfd());
|
||||
pam_end (pamh, ret);
|
||||
exit (E_PAM_ERR);
|
||||
}
|
||||
|
||||
fputs (_("passwd: password updated successfully\n"), shadow_logfd);
|
||||
fputs (_("passwd: password updated successfully\n"), log_get_logfd());
|
||||
(void) pam_end (pamh, PAM_SUCCESS);
|
||||
}
|
||||
#else /* !USE_PAM */
|
||||
|
||||
@ -106,7 +106,6 @@ extern bool console (const char *);
|
||||
/* copydir.c */
|
||||
extern int copy_tree (const char *src_root, const char *dst_root,
|
||||
bool copy_root,
|
||||
bool reset_selinux,
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include <lib/prototypes.h>
|
||||
|
||||
#include "run_part.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/strerrno.h"
|
||||
|
||||
@ -26,14 +26,14 @@ static int run_part(char *script_path, const char *name, const char *action)
|
||||
|
||||
pid=fork();
|
||||
if (pid==-1) {
|
||||
fprintf(shadow_logfd, "fork: %s\n", strerrno());
|
||||
fprintf(log_get_logfd(), "fork: %s\n", strerrno());
|
||||
return 1;
|
||||
}
|
||||
if (pid==0) {
|
||||
setenv("ACTION",action,1);
|
||||
setenv("SUBJECT",name,1);
|
||||
execv(script_path,args);
|
||||
fprintf(shadow_logfd, "execv: %s\n", strerrno());
|
||||
fprintf(log_get_logfd(), "execv: %s\n", strerrno());
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ static int run_part(char *script_path, const char *name, const char *action)
|
||||
return (wait_status);
|
||||
}
|
||||
|
||||
fprintf(shadow_logfd, "wait: %s\n", strerrno());
|
||||
fprintf(log_get_logfd(), "wait: %s\n", strerrno());
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ int run_parts(const char *directory, const char *name, const char *action)
|
||||
|
||||
s = aprintf("%s/%s", directory, namelist[n]->d_name);
|
||||
if (s == NULL) {
|
||||
fprintf(shadow_logfd, "aprintf: %s\n", strerrno());
|
||||
fprintf(log_get_logfd(), "aprintf: %s\n", strerrno());
|
||||
for (; n<scanlist; n++) {
|
||||
free(namelist[n]);
|
||||
}
|
||||
@ -74,7 +74,7 @@ int run_parts(const char *directory, const char *name, const char *action)
|
||||
|
||||
execute_result = 0;
|
||||
if (stat(s, &sb) == -1) {
|
||||
fprintf(shadow_logfd, "stat: %s\n", strerrno());
|
||||
fprintf(log_get_logfd(), "stat: %s\n", strerrno());
|
||||
free(s);
|
||||
for (; n<scanlist; n++) {
|
||||
free(namelist[n]);
|
||||
@ -90,7 +90,7 @@ int run_parts(const char *directory, const char *name, const char *action)
|
||||
free(s);
|
||||
|
||||
if (execute_result!=0) {
|
||||
fprintf(shadow_logfd,
|
||||
fprintf(log_get_logfd(),
|
||||
"%s: did not exit cleanly.\n",
|
||||
namelist[n]->d_name);
|
||||
for (; n<scanlist; n++) {
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
#include <selinux/label.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/strerrno.h"
|
||||
|
||||
@ -138,7 +138,7 @@ static int selinux_log_cb (int type, const char *fmt, ...) {
|
||||
&& (errno != EAFNOSUPPORT)) {
|
||||
|
||||
(void) fputs (_("Cannot open audit interface.\n"),
|
||||
shadow_logfd);
|
||||
log_get_logfd());
|
||||
SYSLOG ((LOG_WARN, "Cannot open audit interface."));
|
||||
}
|
||||
}
|
||||
@ -191,9 +191,9 @@ int check_selinux_permit (const char *perm_name)
|
||||
selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) { .func_log = selinux_log_cb });
|
||||
|
||||
if (getprevcon_raw (&user_context_raw) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: can not get previous SELinux process context: %s\n"),
|
||||
shadow_progname, strerrno());
|
||||
log_get_progname(), strerrno());
|
||||
SYSLOG ((LOG_WARN,
|
||||
"can not get previous SELinux process context: %s",
|
||||
strerrno()));
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
#include "attr.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ static void semanage_error_callback (void *,
|
||||
switch (semanage_msg_get_level (handle)) {
|
||||
case SEMANAGE_MSG_ERR:
|
||||
case SEMANAGE_MSG_WARN:
|
||||
fprintf (shadow_logfd, _("[libsemanage]: %s\n"), message);
|
||||
fprintf (log_get_logfd(), _("[libsemanage]: %s\n"), message);
|
||||
break;
|
||||
case SEMANAGE_MSG_INFO:
|
||||
/* nop */
|
||||
@ -62,7 +62,7 @@ static semanage_handle_t *semanage_init (void)
|
||||
|
||||
handle = semanage_handle_create ();
|
||||
if (NULL == handle) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Cannot create SELinux management handle\n"));
|
||||
return NULL;
|
||||
}
|
||||
@ -71,26 +71,26 @@ static semanage_handle_t *semanage_init (void)
|
||||
|
||||
ret = semanage_is_managed (handle);
|
||||
if (ret != 1) {
|
||||
fprintf (shadow_logfd, _("SELinux policy not managed\n"));
|
||||
fprintf (log_get_logfd(), _("SELinux policy not managed\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = semanage_access_check (handle);
|
||||
if (ret < SEMANAGE_CAN_READ) {
|
||||
fprintf (shadow_logfd, _("Cannot read SELinux policy store\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot read SELinux policy store\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = semanage_connect (handle);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Cannot establish SELinux management connection\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = semanage_begin_transaction (handle);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd, _("Cannot begin SELinux transaction\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot begin SELinux transaction\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ static int semanage_user_mod (semanage_handle_t *handle,
|
||||
|
||||
semanage_seuser_query (handle, key, &seuser);
|
||||
if (NULL == seuser) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Could not query seuser for %s\n"), login_name);
|
||||
ret = 1;
|
||||
goto done;
|
||||
@ -124,7 +124,7 @@ static int semanage_user_mod (semanage_handle_t *handle,
|
||||
if (serange && semanage_mls_enabled(handle)) {
|
||||
ret = semanage_seuser_set_mlsrange (handle, seuser, serange);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Could not set serange for %s to %s\n"),
|
||||
login_name, serange);
|
||||
ret = 1;
|
||||
@ -134,7 +134,7 @@ static int semanage_user_mod (semanage_handle_t *handle,
|
||||
|
||||
ret = semanage_seuser_set_sename (handle, seuser, seuser_name);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Could not set sename for %s\n"),
|
||||
login_name);
|
||||
ret = 1;
|
||||
@ -143,7 +143,7 @@ static int semanage_user_mod (semanage_handle_t *handle,
|
||||
|
||||
ret = semanage_seuser_modify_local (handle, key, seuser);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Could not modify login mapping for %s\n"),
|
||||
login_name);
|
||||
ret = 1;
|
||||
@ -168,7 +168,7 @@ static int semanage_user_add (semanage_handle_t *handle,
|
||||
|
||||
ret = semanage_seuser_create (handle, &seuser);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Cannot create SELinux login mapping for %s\n"),
|
||||
login_name);
|
||||
ret = 1;
|
||||
@ -177,7 +177,7 @@ static int semanage_user_add (semanage_handle_t *handle,
|
||||
|
||||
ret = semanage_seuser_set_name (handle, seuser, login_name);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd, _("Could not set name for %s\n"), login_name);
|
||||
fprintf (log_get_logfd(), _("Could not set name for %s\n"), login_name);
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
@ -185,7 +185,7 @@ static int semanage_user_add (semanage_handle_t *handle,
|
||||
if (serange && semanage_mls_enabled(handle)) {
|
||||
ret = semanage_seuser_set_mlsrange (handle, seuser, serange);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Could not set serange for %s to %s\n"),
|
||||
login_name, serange);
|
||||
ret = 1;
|
||||
@ -195,7 +195,7 @@ static int semanage_user_add (semanage_handle_t *handle,
|
||||
|
||||
ret = semanage_seuser_set_sename (handle, seuser, seuser_name);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Could not set SELinux user for %s\n"),
|
||||
login_name);
|
||||
ret = 1;
|
||||
@ -204,7 +204,7 @@ static int semanage_user_add (semanage_handle_t *handle,
|
||||
|
||||
ret = semanage_seuser_modify_local (handle, key, seuser);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Could not add login mapping for %s\n"),
|
||||
login_name);
|
||||
ret = 1;
|
||||
@ -232,21 +232,21 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
|
||||
|
||||
handle = semanage_init ();
|
||||
if (NULL == handle) {
|
||||
fprintf (shadow_logfd, _("Cannot init SELinux management\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot init SELinux management\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = semanage_seuser_key_create (handle, login_name, &key);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd, _("Cannot create SELinux user key\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot create SELinux user key\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = semanage_seuser_exists (handle, key, &seuser_exists);
|
||||
if (ret < 0) {
|
||||
fprintf (shadow_logfd, _("Cannot verify the SELinux user\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot verify the SELinux user\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
@ -254,7 +254,7 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
|
||||
if (0 != seuser_exists) {
|
||||
ret = semanage_user_mod (handle, key, login_name, seuser_name, serange);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Cannot modify SELinux user mapping\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
@ -262,7 +262,7 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
|
||||
} else {
|
||||
ret = semanage_user_add (handle, key, login_name, seuser_name, serange);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Cannot add SELinux user mapping\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
@ -271,7 +271,7 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
|
||||
|
||||
ret = semanage_commit (handle);
|
||||
if (ret < 0) {
|
||||
fprintf (shadow_logfd, _("Cannot commit SELinux transaction\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot commit SELinux transaction\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
@ -297,27 +297,27 @@ int del_seuser (const char *login_name)
|
||||
|
||||
handle = semanage_init ();
|
||||
if (NULL == handle) {
|
||||
fprintf (shadow_logfd, _("Cannot init SELinux management\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot init SELinux management\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = semanage_seuser_key_create (handle, login_name, &key);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd, _("Cannot create SELinux user key\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot create SELinux user key\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = semanage_seuser_exists (handle, key, &exists);
|
||||
if (ret < 0) {
|
||||
fprintf (shadow_logfd, _("Cannot verify the SELinux user\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot verify the SELinux user\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (0 == exists) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Login mapping for %s is not defined, OK if default mapping was used\n"),
|
||||
login_name);
|
||||
ret = 0; /* probably default mapping */
|
||||
@ -326,13 +326,13 @@ int del_seuser (const char *login_name)
|
||||
|
||||
ret = semanage_seuser_exists_local (handle, key, &exists);
|
||||
if (ret < 0) {
|
||||
fprintf (shadow_logfd, _("Cannot verify the SELinux user\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot verify the SELinux user\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (0 == exists) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Login mapping for %s is defined in policy, cannot be deleted\n"),
|
||||
login_name);
|
||||
ret = 0; /* Login mapping defined in policy can't be deleted */
|
||||
@ -341,7 +341,7 @@ int del_seuser (const char *login_name)
|
||||
|
||||
ret = semanage_seuser_del_local (handle, key);
|
||||
if (ret != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("Could not delete login mapping for %s"),
|
||||
login_name);
|
||||
ret = 1;
|
||||
@ -350,7 +350,7 @@ int del_seuser (const char *login_name)
|
||||
|
||||
ret = semanage_commit (handle);
|
||||
if (ret < 0) {
|
||||
fprintf (shadow_logfd, _("Cannot commit SELinux transaction\n"));
|
||||
fprintf (log_get_logfd(), _("Cannot commit SELinux transaction\n"));
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
#include "atoi/getnum.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
#include "string/strtok/strsep2arr.h"
|
||||
@ -37,7 +36,7 @@
|
||||
* performance reasons. I am going to come up with some conditional
|
||||
* compilation glarp to improve on this in the future.
|
||||
*/
|
||||
// from-string get pasword entry
|
||||
// from-string get password entry
|
||||
struct passwd *
|
||||
sgetpwent(const char *s)
|
||||
{
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
#include "atoi/a2i.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "sizeof.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
#include "shadowlog.h"
|
||||
|
||||
#include "lib/shadowlog_internal.h"
|
||||
|
||||
const char *shadow_progname = "libshadow";
|
||||
FILE *shadow_logfd = NULL;
|
||||
static const char *shadow_progname = "libshadow";
|
||||
static FILE *shadow_logfd = NULL;
|
||||
|
||||
void log_set_progname(const char *progname)
|
||||
{
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#ifndef _SHADOWLOG_INTERNAL_H
|
||||
#define _SHADOWLOG_INTERNAL_H
|
||||
|
||||
extern const char *shadow_progname; /* Program name shown in error messages */
|
||||
extern FILE *shadow_logfd; /* file descriptor to which error messages are printed */
|
||||
|
||||
#endif /* _SHADOWLOG_INTERNAL_H */
|
||||
16
lib/spawn.c
16
lib/spawn.c
@ -15,7 +15,7 @@
|
||||
|
||||
#include "exitcodes.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/strerrno.h"
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ run_command(const char *cmd, const char *argv[],
|
||||
}
|
||||
|
||||
(void) fflush (stdout);
|
||||
(void) fflush (shadow_logfd);
|
||||
(void) fflush (log_get_logfd());
|
||||
|
||||
pid = fork ();
|
||||
if (0 == pid) {
|
||||
@ -39,12 +39,12 @@ run_command(const char *cmd, const char *argv[],
|
||||
if (ENOENT == errno) {
|
||||
_exit (E_CMD_NOTFOUND);
|
||||
}
|
||||
fprintf (shadow_logfd, "%s: cannot execute %s: %s\n",
|
||||
shadow_progname, cmd, strerrno());
|
||||
fprintf (log_get_logfd(), "%s: cannot execute %s: %s\n",
|
||||
log_get_progname(), cmd, strerrno());
|
||||
_exit (E_CMD_NOEXEC);
|
||||
} else if ((pid_t)-1 == pid) {
|
||||
fprintf (shadow_logfd, "%s: cannot execute %s: %s\n",
|
||||
shadow_progname, cmd, strerrno());
|
||||
fprintf (log_get_logfd(), "%s: cannot execute %s: %s\n",
|
||||
log_get_progname(), cmd, strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -56,8 +56,8 @@ run_command(const char *cmd, const char *argv[],
|
||||
|| ((pid_t)-1 != wpid && wpid != pid));
|
||||
|
||||
if ((pid_t)-1 == wpid) {
|
||||
fprintf (shadow_logfd, "%s: waitpid (status: %d): %s\n",
|
||||
shadow_progname, *status, strerrno());
|
||||
fprintf (log_get_logfd(), "%s: waitpid (status: %d): %s\n",
|
||||
log_get_progname(), *status, strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include "exitcodes.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
|
||||
|
||||
@ -57,22 +56,22 @@ sssd_flush_cache(int dbflags)
|
||||
free(sss_cache_args);
|
||||
if (rv != 0) {
|
||||
/* run_command writes its own more detailed message. */
|
||||
SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, shadow_progname));
|
||||
SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, log_get_progname()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
code = WEXITSTATUS (status);
|
||||
if (!WIFEXITED (status)) {
|
||||
SYSLOG ((LOG_WARN, "%s: sss_cache did not terminate normally (signal %d)",
|
||||
shadow_progname, WTERMSIG (status)));
|
||||
log_get_progname(), WTERMSIG (status)));
|
||||
return -1;
|
||||
} else if (code == E_CMD_NOTFOUND) {
|
||||
/* sss_cache is not installed, or it is installed but uses an
|
||||
interpreter that is missing. Probably the former. */
|
||||
return 0;
|
||||
} else if (code != 0) {
|
||||
SYSLOG ((LOG_WARN, "%s: sss_cache exited with status %d", shadow_progname, code));
|
||||
SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, shadow_progname));
|
||||
SYSLOG ((LOG_WARN, "%s: sss_cache exited with status %d", log_get_progname(), code));
|
||||
SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, log_get_progname()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
126
lib/tcbfuncs.c
126
lib/tcbfuncs.c
@ -23,7 +23,7 @@
|
||||
#include "prototypes.h"
|
||||
#include "tcbfuncs.h"
|
||||
#include "shadowio.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
@ -64,8 +64,8 @@ shadowtcb_status shadowtcb_gain_priv (void)
|
||||
* to exit soon.
|
||||
*/
|
||||
#define OUT_OF_MEMORY do { \
|
||||
fprintf (shadow_logfd, _("%s: out of memory\n"), shadow_progname); \
|
||||
(void) fflush (shadow_logfd); \
|
||||
fprintf (log_get_logfd(), _("%s: out of memory\n"), log_get_progname()); \
|
||||
(void) fflush (log_get_logfd()); \
|
||||
} while (false)
|
||||
|
||||
/* Returns user's tcb directory path relative to TCB_DIR. */
|
||||
@ -102,9 +102,9 @@ static /*@null@*/ char *shadowtcb_path_rel_existing (const char *name)
|
||||
return NULL;
|
||||
}
|
||||
if (lstat (path, &st) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot stat %s: %s\n"),
|
||||
shadow_progname, path, strerrno());
|
||||
log_get_progname(), path, strerrno());
|
||||
free (path);
|
||||
return NULL;
|
||||
}
|
||||
@ -118,16 +118,16 @@ static /*@null@*/ char *shadowtcb_path_rel_existing (const char *name)
|
||||
return rval;
|
||||
}
|
||||
if (!S_ISLNK (st.st_mode)) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: %s is neither a directory, nor a symlink.\n"),
|
||||
shadow_progname, path);
|
||||
log_get_progname(), path);
|
||||
free (path);
|
||||
return NULL;
|
||||
}
|
||||
if (readlinknul_a(path, link) == -1) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot read symbolic link %s: %s\n"),
|
||||
shadow_progname, path, strerrno());
|
||||
log_get_progname(), path, strerrno());
|
||||
free (path);
|
||||
return NULL;
|
||||
}
|
||||
@ -186,9 +186,9 @@ static shadowtcb_status mkdir_leading (const char *name, uid_t uid)
|
||||
}
|
||||
ptr = path;
|
||||
if (stat (TCB_DIR, &st) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot stat %s: %s\n"),
|
||||
shadow_progname, TCB_DIR, strerrno());
|
||||
log_get_progname(), TCB_DIR, strerrno());
|
||||
goto out_free_path;
|
||||
}
|
||||
while (NULL != (ind = strchr(ptr, '/'))) {
|
||||
@ -199,21 +199,21 @@ static shadowtcb_status mkdir_leading (const char *name, uid_t uid)
|
||||
return SHADOWTCB_FAILURE;
|
||||
}
|
||||
if ((mkdir (dir, 0700) != 0) && (errno != EEXIST)) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot create directory %s: %s\n"),
|
||||
shadow_progname, dir, strerrno());
|
||||
log_get_progname(), dir, strerrno());
|
||||
goto out_free_dir;
|
||||
}
|
||||
if (chown (dir, 0, st.st_gid) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change owner of %s: %s\n"),
|
||||
shadow_progname, dir, strerrno());
|
||||
log_get_progname(), dir, strerrno());
|
||||
goto out_free_dir;
|
||||
}
|
||||
if (chmod (dir, 0711) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change mode of %s: %s\n"),
|
||||
shadow_progname, dir, strerrno());
|
||||
log_get_progname(), dir, strerrno());
|
||||
goto out_free_dir;
|
||||
}
|
||||
free (dir);
|
||||
@ -242,9 +242,9 @@ static shadowtcb_status unlink_suffs (const char *user)
|
||||
return SHADOWTCB_FAILURE;
|
||||
}
|
||||
if ((unlink (tmp) != 0) && (errno != ENOENT)) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: unlink: %s: %s\n"),
|
||||
shadow_progname, tmp, strerrno());
|
||||
log_get_progname(), tmp, strerrno());
|
||||
free (tmp);
|
||||
return SHADOWTCB_FAILURE;
|
||||
}
|
||||
@ -272,9 +272,9 @@ rmdir_leading(const char *relpath)
|
||||
|
||||
if (rmdir(path) != 0) {
|
||||
if (errno != ENOTEMPTY) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot remove directory %s: %s\n"),
|
||||
shadow_progname, path, strerrno());
|
||||
log_get_progname(), path, strerrno());
|
||||
ret = SHADOWTCB_FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -306,9 +306,9 @@ static shadowtcb_status move_dir (const char *user_newname, uid_t user_newid)
|
||||
goto out_free_nomem;
|
||||
}
|
||||
if (stat (olddir, &oldmode) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot stat %s: %s\n"),
|
||||
shadow_progname, olddir, strerrno());
|
||||
log_get_progname(), olddir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
old_uid = oldmode.st_uid;
|
||||
@ -333,18 +333,18 @@ static shadowtcb_status move_dir (const char *user_newname, uid_t user_newid)
|
||||
goto out_free;
|
||||
}
|
||||
if (rename (real_old_dir, real_new_dir) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot rename %s to %s: %s\n"),
|
||||
shadow_progname, real_old_dir, real_new_dir, strerrno());
|
||||
log_get_progname(), real_old_dir, real_new_dir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (rmdir_leading (real_old_dir_rel) == SHADOWTCB_FAILURE) {
|
||||
goto out_free;
|
||||
}
|
||||
if ((unlink (olddir) != 0) && (errno != ENOENT)) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot remove %s: %s\n"),
|
||||
shadow_progname, olddir, strerrno());
|
||||
log_get_progname(), olddir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
newdir = aprintf(TCB_DIR "/%s", user_newname);
|
||||
@ -357,9 +357,9 @@ static shadowtcb_status move_dir (const char *user_newname, uid_t user_newid)
|
||||
}
|
||||
if ( !streq(real_new_dir, newdir)
|
||||
&& (symlink (real_new_dir_rel, newdir) != 0)) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot create symbolic link %s: %s\n"),
|
||||
shadow_progname, real_new_dir_rel, strerrno());
|
||||
log_get_progname(), real_new_dir_rel, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
ret = SHADOWTCB_SUCCESS;
|
||||
@ -461,53 +461,53 @@ shadowtcb_status shadowtcb_move (/*@NULL@*/const char *user_newname, uid_t user_
|
||||
return SHADOWTCB_FAILURE;
|
||||
}
|
||||
if (stat (tcbdir, &dirmode) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot stat %s: %s\n"),
|
||||
shadow_progname, tcbdir, strerrno());
|
||||
log_get_progname(), tcbdir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (chown (tcbdir, 0, 0) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change owners of %s: %s\n"),
|
||||
shadow_progname, tcbdir, strerrno());
|
||||
log_get_progname(), tcbdir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (chmod (tcbdir, 0700) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change mode of %s: %s\n"),
|
||||
shadow_progname, tcbdir, strerrno());
|
||||
log_get_progname(), tcbdir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (lstat (shadow, &filemode) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot lstat %s: %s\n"),
|
||||
shadow_progname, shadow, strerrno());
|
||||
log_get_progname(), shadow, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Warning, user %s has no tcb shadow file.\n"),
|
||||
shadow_progname, user_newname);
|
||||
log_get_progname(), user_newname);
|
||||
} else {
|
||||
if (!S_ISREG (filemode.st_mode) ||
|
||||
filemode.st_nlink != 1) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Emergency: %s's tcb shadow is not a "
|
||||
"regular file with st_nlink=1.\n"
|
||||
"The account is left locked.\n"),
|
||||
shadow_progname, user_newname);
|
||||
log_get_progname(), user_newname);
|
||||
goto out_free;
|
||||
}
|
||||
if (chown (shadow, user_newid, filemode.st_gid) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change owner of %s: %s\n"),
|
||||
shadow_progname, shadow, strerrno());
|
||||
log_get_progname(), shadow, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (chmod (shadow, filemode.st_mode & 07777) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change mode of %s: %s\n"),
|
||||
shadow_progname, shadow, strerrno());
|
||||
log_get_progname(), shadow, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
@ -515,15 +515,15 @@ shadowtcb_status shadowtcb_move (/*@NULL@*/const char *user_newname, uid_t user_
|
||||
goto out_free;
|
||||
}
|
||||
if (chown (tcbdir, user_newid, dirmode.st_gid) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change owner of %s: %s\n"),
|
||||
shadow_progname, tcbdir, strerrno());
|
||||
log_get_progname(), tcbdir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (chmod (tcbdir, dirmode.st_mode & 07777) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change mode of %s: %s\n"),
|
||||
shadow_progname, tcbdir, strerrno());
|
||||
log_get_progname(), tcbdir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
ret = SHADOWTCB_SUCCESS;
|
||||
@ -546,9 +546,9 @@ shadowtcb_status shadowtcb_create (const char *name, uid_t uid)
|
||||
return SHADOWTCB_SUCCESS;
|
||||
}
|
||||
if (stat (TCB_DIR, &tcbdir_stat) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot stat %s: %s\n"),
|
||||
shadow_progname, TCB_DIR, strerrno());
|
||||
log_get_progname(), TCB_DIR, strerrno());
|
||||
return SHADOWTCB_FAILURE;
|
||||
}
|
||||
shadowgid = tcbdir_stat.st_gid;
|
||||
@ -571,39 +571,39 @@ shadowtcb_status shadowtcb_create (const char *name, uid_t uid)
|
||||
return SHADOWTCB_FAILURE;
|
||||
}
|
||||
if (mkdir (dir, 0700) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
_("%s: mkdir: %s: %s\n"), shadow_progname, dir, strerrno());
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: mkdir: %s: %s\n"), log_get_progname(), dir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
fd = open (shadow, O_RDWR | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot open %s: %s\n"),
|
||||
shadow_progname, shadow, strerrno());
|
||||
log_get_progname(), shadow, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (fchown (fd, 0, authgid) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change owner of %s: %s\n"),
|
||||
shadow_progname, shadow, strerrno());
|
||||
log_get_progname(), shadow, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (fchmod (fd, (mode_t) ((authgid == shadowgid) ? 0600 : 0640)) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change mode of %s: %s\n"),
|
||||
shadow_progname, shadow, strerrno());
|
||||
log_get_progname(), shadow, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (chown (dir, 0, authgid) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change owner of %s: %s\n"),
|
||||
shadow_progname, dir, strerrno());
|
||||
log_get_progname(), dir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if (chmod (dir, (mode_t) ((authgid == shadowgid) ? 02700 : 02710)) != 0) {
|
||||
fprintf (shadow_logfd,
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: Cannot change mode of %s: %s\n"),
|
||||
shadow_progname, dir, strerrno());
|
||||
log_get_progname(), dir, strerrno());
|
||||
goto out_free;
|
||||
}
|
||||
if ( (shadowtcb_set_user (name) == SHADOWTCB_FAILURE)
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
* After a yes/no question, this function gets the answer from the
|
||||
* user.
|
||||
*
|
||||
* Calls to this function will normally be preceeded by a prompt on
|
||||
* Calls to this function will normally be preceded by a prompt on
|
||||
* stdout, so we should fflush(3).
|
||||
*
|
||||
* Return value
|
||||
|
||||
@ -14,7 +14,6 @@ MISCLIBS = \
|
||||
$(LIBECONF) \
|
||||
$(LIBCRYPT) \
|
||||
$(LIBACL) \
|
||||
$(LIBATTR) \
|
||||
$(LIBTCB) \
|
||||
$(LIBPAM)
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
bool subid_init(const char *progname, FILE * logfd)
|
||||
{
|
||||
FILE *shadow_logfd;
|
||||
FILE *fp;
|
||||
if (progname) {
|
||||
progname = strdup(progname);
|
||||
if (!progname)
|
||||
@ -35,12 +35,12 @@ bool subid_init(const char *progname, FILE * logfd)
|
||||
log_set_logfd(logfd);
|
||||
return true;
|
||||
}
|
||||
shadow_logfd = fopen("/dev/null", "w");
|
||||
if (!shadow_logfd) {
|
||||
fp = fopen("/dev/null", "w");
|
||||
if (!fp) {
|
||||
log_set_logfd(stderr);
|
||||
return false;
|
||||
}
|
||||
log_set_logfd(shadow_logfd);
|
||||
log_set_logfd(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,6 @@ man_MANS = \
|
||||
man5/gshadow.5 \
|
||||
man1/login.1 \
|
||||
man5/login.defs.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/newusers.8 \
|
||||
man8/nologin.8 \
|
||||
@ -95,7 +94,6 @@ man_XMANS = \
|
||||
login.1.xml \
|
||||
login.access.5.xml \
|
||||
login.defs.5.xml \
|
||||
logoutd.8.xml \
|
||||
newgidmap.1.xml \
|
||||
newgrp.1.xml \
|
||||
newuidmap.1.xml \
|
||||
|
||||
@ -270,7 +270,7 @@
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id='configuration'>
|
||||
<refsect1 id='configuration' condition="tcb">
|
||||
<title>CONFIGURATION</title>
|
||||
<para>
|
||||
The following configuration variables in
|
||||
|
||||
@ -22,6 +22,5 @@ man_MANS += man8/lastlog.8
|
||||
endif
|
||||
|
||||
EXTRA_DIST = $(man_MANS) \
|
||||
man8/groupmems.8 \
|
||||
man8/logoutd.8
|
||||
man8/groupmems.8
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@ man_MANS = \
|
||||
man1/chfn.1 \
|
||||
man8/groupdel.8 \
|
||||
man5/gshadow.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/nologin.8 \
|
||||
man1/sg.1 \
|
||||
|
||||
@ -22,7 +22,6 @@ man_MANS = \
|
||||
man5/gshadow.5 \
|
||||
man1/login.1 \
|
||||
man5/login.defs.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/newusers.8 \
|
||||
man8/nologin.8 \
|
||||
|
||||
@ -22,7 +22,6 @@ man_MANS = \
|
||||
man5/gshadow.5 \
|
||||
man1/login.1 \
|
||||
man5/login.defs.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/newusers.8 \
|
||||
man8/nologin.8 \
|
||||
|
||||
@ -84,7 +84,7 @@
|
||||
<listitem>
|
||||
<para>Add a user to the group membership list.</para>
|
||||
<para condition="gshadow">
|
||||
If the <filename>/etc/gshadow</filename> file exist, and the
|
||||
If the <filename>/etc/gshadow</filename> file exists, and the
|
||||
group has no entry in the <filename>/etc/gshadow</filename>
|
||||
file, a new entry will be created.
|
||||
</para>
|
||||
@ -95,12 +95,12 @@
|
||||
<listitem>
|
||||
<para>Delete a user from the group membership list.</para>
|
||||
<para condition="gshadow">
|
||||
If the <filename>/etc/gshadow</filename> file exist, the user
|
||||
If the <filename>/etc/gshadow</filename> file exists, the user
|
||||
will be removed from the list of members and administrators of
|
||||
the group.
|
||||
</para>
|
||||
<para condition="gshadow">
|
||||
If the <filename>/etc/gshadow</filename> file exist, and the
|
||||
If the <filename>/etc/gshadow</filename> file exists, and the
|
||||
group has no entry in the <filename>/etc/gshadow</filename>
|
||||
file, a new entry will be created.
|
||||
</para>
|
||||
@ -131,7 +131,7 @@
|
||||
<listitem>
|
||||
<para>Purge all users from the group membership list.</para>
|
||||
<para condition="gshadow">
|
||||
If the <filename>/etc/gshadow</filename> file exist, and the
|
||||
If the <filename>/etc/gshadow</filename> file exists, and the
|
||||
group has no entry in the <filename>/etc/gshadow</filename>
|
||||
file, a new entry will be created.
|
||||
</para>
|
||||
|
||||
@ -22,7 +22,6 @@ man_MANS = \
|
||||
man5/gshadow.5 \
|
||||
man1/login.1 \
|
||||
man5/login.defs.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/newusers.8 \
|
||||
man8/nologin.8 \
|
||||
|
||||
@ -18,7 +18,6 @@ man_MANS = \
|
||||
man8/grpunconv.8 \
|
||||
man1/login.1 \
|
||||
man5/login.defs.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/newusers.8 \
|
||||
man1/passwd.1 \
|
||||
|
||||
@ -379,7 +379,6 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<!-- logoutd: no variables -->
|
||||
<varlistentry>
|
||||
<term>newgrp / sg</term>
|
||||
<listitem>
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 1991 , Julianne Frances Haugh
|
||||
SPDX-FileCopyrightText: 2007 - 2008, Nicolas François
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
-->
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!-- SHADOW-CONFIG-HERE -->
|
||||
]>
|
||||
<refentry id='logoutd.8'>
|
||||
<!-- $Id$ -->
|
||||
<refentryinfo>
|
||||
<author>
|
||||
<firstname>Julianne Frances</firstname>
|
||||
<surname>Haugh</surname>
|
||||
<contrib>Creation, 1991</contrib>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Kłoczko</surname>
|
||||
<email>kloczek@pld.org.pl</email>
|
||||
<contrib>shadow-utils maintainer, 2000 - 2007</contrib>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Nicolas</firstname>
|
||||
<surname>François</surname>
|
||||
<email>nicolas.francois@centraliens.net</email>
|
||||
<contrib>shadow-utils maintainer, 2007 - now</contrib>
|
||||
</author>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>logoutd</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
<refmiscinfo class="sectdesc">System Management Commands</refmiscinfo>
|
||||
<refmiscinfo class="source">shadow-utils</refmiscinfo>
|
||||
<refmiscinfo class="version">&SHADOW_UTILS_VERSION;</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv id='name'>
|
||||
<refname>logoutd</refname>
|
||||
<refpurpose>enforce login time restrictions</refpurpose>
|
||||
</refnamediv>
|
||||
<!-- body begins here -->
|
||||
<refsynopsisdiv id='synopsis'>
|
||||
<cmdsynopsis>
|
||||
<command>logoutd</command>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1 id='description'>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
<command>logoutd</command> enforces the login time and port
|
||||
restrictions specified in <filename>/etc/porttime</filename>.
|
||||
<command>logoutd</command> should be started from
|
||||
<filename>/etc/rc</filename>. The <filename>/var/run/utmp</filename>
|
||||
file is scanned periodically and each user name is checked to see if
|
||||
the named user is permitted on the named port at the current time.
|
||||
Any login session which is violating the restrictions in
|
||||
<filename>/etc/porttime</filename> is terminated.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id='files'>
|
||||
<title>FILES</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>/etc/porttime</filename></term>
|
||||
<listitem>
|
||||
<para>File containing port access.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>/var/run/utmp</filename></term>
|
||||
<listitem>
|
||||
<para>List of current login sessions.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
@ -14,7 +14,6 @@ man_MANS = \
|
||||
man8/groupmems.8 \
|
||||
man8/groupmod.8 \
|
||||
man8/grpck.8 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man1/sg.1 \
|
||||
man3/shadow.3 \
|
||||
|
||||
@ -90,6 +90,7 @@ $(DOMAIN).pot-update: $(XMLFILES) $(srcdir)/XMLFILES
|
||||
@set -ex; tmpdir=`mktemp -d`; \
|
||||
origdir=`pwd`; \
|
||||
cd $(top_srcdir)/man; \
|
||||
cp -r login.defs.d $$tmpdir/; \
|
||||
cp *.xml $$tmpdir/; \
|
||||
files=""; \
|
||||
for file in $(notdir $(XMLFILES)); do \
|
||||
|
||||
@ -20,7 +20,6 @@ XMLFILES = \
|
||||
$(top_srcdir)/man/login.1.xml \
|
||||
$(top_srcdir)/man/login.access.5.xml \
|
||||
$(top_srcdir)/man/login.defs.5.xml \
|
||||
$(top_srcdir)/man/logoutd.8.xml \
|
||||
$(top_srcdir)/man/newgrp.1.xml \
|
||||
$(top_srcdir)/man/newusers.8.xml \
|
||||
$(top_srcdir)/man/nologin.8.xml \
|
||||
|
||||
@ -22,7 +22,6 @@ man_MANS = \
|
||||
man5/gshadow.5 \
|
||||
man1/login.1 \
|
||||
man5/login.defs.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/newusers.8 \
|
||||
man8/nologin.8 \
|
||||
|
||||
@ -82,8 +82,12 @@
|
||||
If the password field begins with an exclamation mark <emphasis>!</emphasis>,
|
||||
the password is locked.
|
||||
The remaining characters on the
|
||||
line represent the password field before the password was
|
||||
locked.
|
||||
line represent the password hash.
|
||||
</para>
|
||||
<para>
|
||||
If the password hash consists of a star <emphasis>*</emphasis>,
|
||||
password access is effectively disallowed;
|
||||
this is because no password can produce a hash like this.
|
||||
</para>
|
||||
<para>
|
||||
Refer to <citerefentry><refentrytitle>crypt</refentrytitle>
|
||||
|
||||
@ -14,7 +14,6 @@ man_MANS = \
|
||||
man8/groupmod.8 \
|
||||
man8/grpck.8 \
|
||||
man5/gshadow.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/nologin.8 \
|
||||
man1/passwd.1 \
|
||||
|
||||
@ -22,7 +22,6 @@ man_MANS = \
|
||||
man5/gshadow.5 \
|
||||
man1/login.1 \
|
||||
man5/login.defs.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/newusers.8 \
|
||||
man8/nologin.8 \
|
||||
|
||||
@ -134,6 +134,33 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--btrfs-subvolume-home</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Create the user's home directory as a Btrfs subvolume.
|
||||
</para>
|
||||
<para>
|
||||
If this option is not specified,
|
||||
<command>useradd</command> will follow the default behavior
|
||||
defined by the <option>BTRFS_SUBVOLUME_HOME</option> variable
|
||||
in <filename>/etc/default/useradd</filename>.
|
||||
If this variable is not set, the default value is no.
|
||||
</para>
|
||||
<para>
|
||||
When the <option>--btrfs-subvolume-home</option> command-line option
|
||||
is specified,
|
||||
a Btrfs subvolume is created
|
||||
regardless of any configuration file settings.
|
||||
</para>
|
||||
<para>
|
||||
Note: this feature works only if the underlying filesystem supports
|
||||
Btrfs subvolumes.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-c</option>, <option>--comment</option> <replaceable>COMMENT</replaceable>
|
||||
@ -160,7 +187,7 @@
|
||||
login directory name.
|
||||
The directory <replaceable>HOME_DIR</replaceable> is not created by
|
||||
default. However it will be created for non-system users if either the
|
||||
<option>-m</option> flag is specifed or
|
||||
<option>-m</option> flag is specified or
|
||||
<replaceable>CREATE_HOME</replaceable> in
|
||||
<filename>login.defs</filename> is set to true. However, it will never
|
||||
be created if the <option>-M</option> flag is specified.
|
||||
|
||||
@ -22,7 +22,6 @@ man_MANS = \
|
||||
man5/gshadow.5 \
|
||||
man1/login.1 \
|
||||
man5/login.defs.5 \
|
||||
man8/logoutd.8 \
|
||||
man1/newgrp.1 \
|
||||
man8/newusers.8 \
|
||||
man8/nologin.8 \
|
||||
|
||||
@ -92,7 +92,6 @@ src/grpunconv.c
|
||||
src/lastlog.c
|
||||
src/login.c
|
||||
src/login_nopam.c
|
||||
src/logoutd.c
|
||||
src/newgidmap.c
|
||||
src/newgrp.c
|
||||
src/newuidmap.c
|
||||
|
||||
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@ -15,7 +15,6 @@
|
||||
/grpunconv
|
||||
/lastlog
|
||||
/login
|
||||
/logoutd
|
||||
/newgrp
|
||||
/newgidmap
|
||||
/newuidmap
|
||||
|
||||
@ -48,7 +48,6 @@ usbin_PROGRAMS = \
|
||||
grpck \
|
||||
grpconv \
|
||||
grpunconv \
|
||||
logoutd \
|
||||
newusers \
|
||||
pwck \
|
||||
pwconv \
|
||||
@ -70,9 +69,6 @@ endif
|
||||
if !WITH_TCB
|
||||
suidubins += passwd
|
||||
endif
|
||||
if ACCT_TOOLS_SETUID
|
||||
suidusbins += chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
|
||||
endif
|
||||
if ENABLE_SUBIDS
|
||||
if !FCAPS
|
||||
suidubins += newgidmap newuidmap
|
||||
@ -87,12 +83,6 @@ LDADD = $(INTLLIBS) \
|
||||
$(top_builddir)/lib/libshadow.la \
|
||||
$(LIBTCB)
|
||||
|
||||
if ACCT_TOOLS_SETUID
|
||||
LIBPAM_SUID = $(LIBPAM)
|
||||
else
|
||||
LIBPAM_SUID =
|
||||
endif
|
||||
|
||||
if USE_PAM
|
||||
LIBCRYPT_NOPAM =
|
||||
else
|
||||
@ -103,15 +93,15 @@ chage_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
|
||||
newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl
|
||||
newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl
|
||||
chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
|
||||
chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
|
||||
chgpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
|
||||
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
|
||||
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl
|
||||
expiry_LDADD = $(LDADD) $(LIBECONF)
|
||||
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
|
||||
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
|
||||
groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
|
||||
groupadd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
|
||||
groupdel_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
|
||||
groupmems_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||
groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
|
||||
groupmod_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
|
||||
grpck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||
grpconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||
grpunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||
@ -132,9 +122,9 @@ su_SOURCES = \
|
||||
suauth.c
|
||||
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) $(LIBSELINUX)
|
||||
sulogin_LDADD = $(LDADD) $(LIBCRYPT) $(LIBECONF)
|
||||
useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl
|
||||
userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) -ldl
|
||||
usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl
|
||||
useradd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBECONF) -ldl
|
||||
userdel_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) -ldl
|
||||
usermod_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBECONF) -ldl
|
||||
vipw_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||
|
||||
install-am: all-am
|
||||
|
||||
@ -18,11 +18,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
#include "atoi/a2i.h"
|
||||
#include "defines.h"
|
||||
#include "nscd.h"
|
||||
@ -80,7 +75,6 @@ NORETURN static void fail_exit (int code, bool process_selinux);
|
||||
NORETURN static void usage (int status);
|
||||
static void process_flags (int argc, char **argv, struct option_flags *flags);
|
||||
static void check_flags (void);
|
||||
static void check_perms (void);
|
||||
static void open_files (bool process_selinux);
|
||||
static void close_files(const struct option_flags *flags);
|
||||
|
||||
@ -292,56 +286,6 @@ static void check_flags (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check_perms - check if the caller is allowed to add a group
|
||||
*
|
||||
* With PAM support, the setuid bit can be set on chgpasswd to allow
|
||||
* non-root users to groups.
|
||||
* Without PAM support, only users who can write in the group databases
|
||||
* can add groups.
|
||||
*
|
||||
* It will not return if the user is not allowed.
|
||||
*/
|
||||
static void check_perms (void)
|
||||
{
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
struct passwd *pampw;
|
||||
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (NULL == pampw) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
exit (1);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
}
|
||||
|
||||
/*
|
||||
* open_files - lock and open the group databases
|
||||
*/
|
||||
@ -463,8 +407,6 @@ int main (int argc, char **argv)
|
||||
|
||||
OPENLOG (Prog);
|
||||
|
||||
check_perms ();
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
|
||||
@ -79,7 +79,6 @@ NORETURN static void fail_exit (int code, bool process_selinux);
|
||||
NORETURN static void usage (int status);
|
||||
static void process_flags (int argc, char **argv, struct option_flags *flags);
|
||||
static void check_flags (void);
|
||||
static void check_perms (void);
|
||||
static void open_files(const struct option_flags *flags);
|
||||
static void close_files(const struct option_flags *flags);
|
||||
|
||||
@ -288,60 +287,6 @@ static void check_flags (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check_perms - check if the caller is allowed to add a group
|
||||
*
|
||||
* With PAM support, the setuid bit can be set on chpasswd to allow
|
||||
* non-root users to groups.
|
||||
* Without PAM support, only users who can write in the group databases
|
||||
* can add groups.
|
||||
*
|
||||
* It will not return if the user is not allowed.
|
||||
*/
|
||||
static void check_perms (void)
|
||||
{
|
||||
#ifdef USE_PAM
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
/* If chpasswd uses PAM and is SUID, check the permissions,
|
||||
* otherwise, the permissions are enforced by the access to the
|
||||
* passwd and shadow files.
|
||||
*/
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
struct passwd *pampw;
|
||||
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (NULL == pampw) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
exit (1);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
#endif /* USE_PAM */
|
||||
}
|
||||
|
||||
/*
|
||||
* open_files - lock and open the password databases
|
||||
*/
|
||||
@ -503,8 +448,6 @@ int main (int argc, char **argv)
|
||||
|
||||
OPENLOG (Prog);
|
||||
|
||||
check_perms ();
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (!use_pam)
|
||||
#endif /* USE_PAM */
|
||||
@ -576,7 +519,7 @@ int main (int argc, char **argv)
|
||||
|
||||
/*
|
||||
* Prevent adding a non valid hash to /etc/shadow and
|
||||
* potentialy lock account
|
||||
* potentially lock account
|
||||
*/
|
||||
|
||||
if (eflg) {
|
||||
|
||||
@ -5,10 +5,9 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "atoi/a2i.h"
|
||||
#include "string/strerrno.h"
|
||||
#include "subid.h"
|
||||
#include "stdlib.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
|
||||
/* Test program for the subid freeing routine */
|
||||
@ -29,8 +28,8 @@ int main(int argc, char *argv[])
|
||||
struct subordinate_range range;
|
||||
bool group = false; // get subuids by default
|
||||
|
||||
log_set_progname(Prog);
|
||||
log_set_logfd(stderr);
|
||||
if (!subid_init(Prog, stderr))
|
||||
fprintf(stderr, "subid_init: %s\n", strerrno());
|
||||
while ((c = getopt(argc, argv, "g")) != EOF) {
|
||||
switch(c) {
|
||||
case 'g': group = true; break;
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
#include "atoi/getnum.h"
|
||||
#include "attr.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
#include "stdlib.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strerrno.h"
|
||||
#include "subid.h"
|
||||
|
||||
|
||||
@ -24,8 +24,8 @@ int main(int argc, char *argv[])
|
||||
uid_t u;
|
||||
uid_t *uids;
|
||||
|
||||
log_set_progname(Prog);
|
||||
log_set_logfd(stderr);
|
||||
if (!subid_init(Prog, stderr))
|
||||
fprintf(stderr, "subid_init: %s\n", strerrno());
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
|
||||
#include "attr.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strerrno.h"
|
||||
#include "subid.h"
|
||||
|
||||
static const char Prog[] = "getsubids";
|
||||
@ -22,8 +22,8 @@ int main(int argc, char *argv[])
|
||||
struct subid_range *ranges;
|
||||
const char *owner;
|
||||
|
||||
log_set_progname(Prog);
|
||||
log_set_logfd(stderr);
|
||||
if (!subid_init(Prog, stderr))
|
||||
fprintf(stderr, "subid_init: %s\n", strerrno());
|
||||
if (argc < 2)
|
||||
usage();
|
||||
owner = argv[1];
|
||||
|
||||
@ -18,12 +18,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
#include <pwd.h>
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
#include "atoi/getnum.h"
|
||||
#include "chkname.h"
|
||||
@ -100,7 +94,6 @@ static void close_files(const struct option_flags *flags);
|
||||
static void open_files(const struct option_flags *flags);
|
||||
static void process_flags (int argc, char **argv, struct option_flags *flags);
|
||||
static void check_flags (void);
|
||||
static void check_perms (void);
|
||||
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
@ -550,56 +543,6 @@ static void check_flags (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check_perms - check if the caller is allowed to add a group
|
||||
*
|
||||
* With PAM support, the setuid bit can be set on groupadd to allow
|
||||
* non-root users to groups.
|
||||
* Without PAM support, only users who can write in the group databases
|
||||
* can add groups.
|
||||
*
|
||||
* It will not return if the user is not allowed.
|
||||
*/
|
||||
static void check_perms (void)
|
||||
{
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
struct passwd *pampw;
|
||||
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (NULL == pampw) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
fail_exit (1);
|
||||
}
|
||||
|
||||
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
fail_exit (1);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
}
|
||||
|
||||
/*
|
||||
* main - groupadd command
|
||||
*/
|
||||
@ -634,8 +577,6 @@ int main (int argc, char **argv)
|
||||
*/
|
||||
process_flags (argc, argv, &flags);
|
||||
|
||||
check_perms ();
|
||||
|
||||
if (run_parts ("/etc/shadow-maint/groupadd-pre.d", group_name,
|
||||
Prog)) {
|
||||
exit(1);
|
||||
|
||||
@ -15,11 +15,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <getopt.h>
|
||||
@ -362,12 +357,6 @@ static void process_flags (int argc, char **argv, struct option_flags *flags)
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
struct option_flags flags = {.chroot = false, .prefix = false};
|
||||
|
||||
log_set_progname(Prog);
|
||||
@ -394,41 +383,6 @@ int main (int argc, char **argv)
|
||||
|
||||
process_flags (argc, argv, &flags);
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
{
|
||||
struct passwd *pampw;
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (pampw == NULL) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
fail_exit (1);
|
||||
}
|
||||
|
||||
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
fail_exit (1);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
|
||||
@ -20,12 +20,6 @@
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
#include <pwd.h>
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
#include "alloc/malloc.h"
|
||||
#include "atoi/getnum.h"
|
||||
@ -783,12 +777,6 @@ void update_primary_groups (gid_t ogid, gid_t ngid)
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
struct option_flags flags = {.chroot = false, .prefix = false};
|
||||
|
||||
log_set_progname(Prog);
|
||||
@ -815,42 +803,6 @@ int main (int argc, char **argv)
|
||||
|
||||
process_flags (argc, argv, &flags);
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
{
|
||||
struct passwd *pampw;
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (NULL == pampw) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
exit (E_PAM_USERNAME);
|
||||
}
|
||||
|
||||
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
exit (E_PAM_ERROR);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
|
||||
252
src/logoutd.c
252
src/logoutd.c
@ -1,252 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1991 - 1993, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <utmpx.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
#include "sizeof.h"
|
||||
#include "string/strcmp/strneq.h"
|
||||
#include "string/strcpy/strncat.h"
|
||||
#include "string/strdup/strndupa.h"
|
||||
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static const char Prog[] = "logoutd";
|
||||
|
||||
#ifndef DEFAULT_HUP_MESG
|
||||
#define DEFAULT_HUP_MESG _("login time exceeded\n\n")
|
||||
#endif
|
||||
|
||||
#ifndef HUP_MESG_FILE
|
||||
#define HUP_MESG_FILE "/etc/logoutd.mesg"
|
||||
#endif
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
static int check_login (const struct utmpx *ut);
|
||||
static void send_mesg_to_tty (int tty_fd);
|
||||
|
||||
|
||||
/*
|
||||
* check_login - check if user (struct utmpx) allowed to stay logged in
|
||||
*/
|
||||
static int
|
||||
check_login(const struct utmpx *ut)
|
||||
{
|
||||
char *user;
|
||||
char *line;
|
||||
time_t now;
|
||||
|
||||
user = strndupa_a(ut->ut_user);
|
||||
line = strndupa_a(ut->ut_line);
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
return isttytime(user, line, now);
|
||||
}
|
||||
|
||||
|
||||
static void send_mesg_to_tty (int tty_fd)
|
||||
{
|
||||
TERMIO oldt, newt;
|
||||
FILE *mesg_file, *tty_file;
|
||||
bool is_tty;
|
||||
|
||||
tty_file = fdopen (tty_fd, "w");
|
||||
if (NULL == tty_file) {
|
||||
return;
|
||||
}
|
||||
|
||||
is_tty = (GTTY (tty_fd, &oldt) == 0);
|
||||
if (is_tty) {
|
||||
/* Suggested by Ivan Nejgebauar <ian@unsux.ns.ac.yu>:
|
||||
set OPOST before writing the message. */
|
||||
newt = oldt;
|
||||
newt.c_oflag |= OPOST;
|
||||
STTY (tty_fd, &newt);
|
||||
}
|
||||
|
||||
mesg_file = fopen (HUP_MESG_FILE, "r");
|
||||
if (NULL != mesg_file) {
|
||||
int c;
|
||||
while ((c = getc (mesg_file)) != EOF) {
|
||||
if (c == '\n') {
|
||||
putc ('\r', tty_file);
|
||||
}
|
||||
putc (c, tty_file);
|
||||
}
|
||||
fclose (mesg_file);
|
||||
} else {
|
||||
fputs (DEFAULT_HUP_MESG, tty_file);
|
||||
}
|
||||
fflush (tty_file);
|
||||
fclose (tty_file);
|
||||
|
||||
if (is_tty) {
|
||||
STTY (tty_fd, &oldt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* logoutd - logout daemon to enforce /etc/porttime file policy
|
||||
*
|
||||
* logoutd is started at system boot time and enforces the login
|
||||
* time and port restrictions specified in /etc/porttime. The
|
||||
* utmp file is periodically scanned and offending users are logged
|
||||
* off from the system.
|
||||
*/
|
||||
int
|
||||
main(int argc, char *[])
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
if (1 != argc) {
|
||||
(void) fputs (_("Usage: logoutd\n"), stderr);
|
||||
}
|
||||
|
||||
(void) setlocale (LC_ALL, "");
|
||||
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
(void) textdomain (PACKAGE);
|
||||
|
||||
#ifndef DEBUG
|
||||
for (int i = 0; close(i) == 0; i++);
|
||||
|
||||
setpgrp ();
|
||||
|
||||
/*
|
||||
* Put this process in the background.
|
||||
*/
|
||||
pid = fork ();
|
||||
if (pid > 0) {
|
||||
/* parent */
|
||||
exit (EXIT_SUCCESS);
|
||||
} else if (pid < 0) {
|
||||
/* error */
|
||||
perror ("fork");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
#endif /* !DEBUG */
|
||||
|
||||
/*
|
||||
* Start syslogging everything
|
||||
*/
|
||||
log_set_progname(Prog);
|
||||
log_set_logfd(stderr);
|
||||
|
||||
OPENLOG (Prog);
|
||||
|
||||
/*
|
||||
* Scan the utmp file once per minute looking for users that
|
||||
* are not supposed to still be logged in.
|
||||
*/
|
||||
while (true) {
|
||||
struct utmpx *ut;
|
||||
|
||||
/*
|
||||
* Attempt to re-open the utmp file. The file is only
|
||||
* open while it is being used.
|
||||
*/
|
||||
setutxent();
|
||||
|
||||
/*
|
||||
* Read all of the entries in the utmp file. The entries
|
||||
* for login sessions will be checked to see if the user
|
||||
* is permitted to be signed on at this time.
|
||||
*/
|
||||
while (NULL != (ut = getutxent())) {
|
||||
int tty_fd;
|
||||
char tty_name[sizeof(ut->ut_line) + 6]; // /dev/ + NUL
|
||||
|
||||
if (ut->ut_type != USER_PROCESS) {
|
||||
continue;
|
||||
}
|
||||
if (strneq_a(ut->ut_user, ""))
|
||||
continue;
|
||||
|
||||
if (check_login (ut)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the rest of this in a child process. This
|
||||
* keeps the scan from waiting on other ports to die.
|
||||
*/
|
||||
|
||||
pid = fork ();
|
||||
if (pid > 0) {
|
||||
/* parent */
|
||||
continue;
|
||||
} else if (pid < 0) {
|
||||
/* failed - give up until the next scan */
|
||||
break;
|
||||
}
|
||||
/* child */
|
||||
|
||||
if (strncmp(ut->ut_line, "/dev/", 5) != 0)
|
||||
strcpy(tty_name, "/dev/");
|
||||
else
|
||||
strcpy(tty_name, "");
|
||||
|
||||
strncat_a(tty_name, ut->ut_line);
|
||||
#ifndef O_NOCTTY
|
||||
#define O_NOCTTY 0
|
||||
#endif
|
||||
tty_fd =
|
||||
open (tty_name, O_WRONLY | O_NDELAY | O_NOCTTY);
|
||||
if (tty_fd != -1) {
|
||||
send_mesg_to_tty (tty_fd);
|
||||
close (tty_fd);
|
||||
sleep (10);
|
||||
}
|
||||
|
||||
if (ut->ut_pid > 1) {
|
||||
kill (-ut->ut_pid, SIGHUP);
|
||||
sleep (10);
|
||||
kill (-ut->ut_pid, SIGKILL);
|
||||
}
|
||||
|
||||
SYSLOG ((LOG_NOTICE,
|
||||
"logged off user '%s' on '%s'",
|
||||
strndupa_a(ut->ut_user),
|
||||
tty_name));
|
||||
|
||||
/*
|
||||
* This child has done all it can, drop dead.
|
||||
*/
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
endutxent();
|
||||
|
||||
#ifndef DEBUG
|
||||
sleep (60);
|
||||
#endif
|
||||
/*
|
||||
* Reap any dead babies ...
|
||||
*/
|
||||
while (wait(NULL) != -1);
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -4,10 +4,9 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "atoi/a2i.h"
|
||||
#include "string/strerrno.h"
|
||||
#include "subid.h"
|
||||
#include "stdlib.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
|
||||
/* Test program for the subid creation routine */
|
||||
@ -31,8 +30,8 @@ int main(int argc, char *argv[])
|
||||
bool group = false; // get subuids by default
|
||||
bool ok;
|
||||
|
||||
log_set_progname(Prog);
|
||||
log_set_logfd(stderr);
|
||||
if (!subid_init(Prog, stderr))
|
||||
fprintf(stderr, "subid_init: %s\n", strerrno());
|
||||
while ((c = getopt(argc, argv, "gn")) != EOF) {
|
||||
switch(c) {
|
||||
case 'n': makenew = true; break;
|
||||
|
||||
@ -36,11 +36,6 @@
|
||||
#include "atoi/a2i.h"
|
||||
#include "atoi/getnum.h"
|
||||
#include "attr.h"
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
#include "chkname.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
@ -118,7 +113,6 @@ static int update_passwd (struct passwd *, const char *);
|
||||
static int add_passwd (struct passwd *, const char *);
|
||||
static void process_flags (int argc, char **argv, struct option_flags *flags);
|
||||
static void check_flags (void);
|
||||
static void check_perms(const struct option_flags *flags);
|
||||
static void open_files (bool process_selinux);
|
||||
static void close_files(const struct option_flags *flags);
|
||||
|
||||
@ -788,60 +782,6 @@ static void check_flags (void)
|
||||
#endif /* !USE_PAM */
|
||||
}
|
||||
|
||||
/*
|
||||
* check_perms - check if the caller is allowed to add a group
|
||||
*
|
||||
* With PAM support, the setuid bit can be set on groupadd to allow
|
||||
* non-root users to groups.
|
||||
* Without PAM support, only users who can write in the group databases
|
||||
* can add groups.
|
||||
*
|
||||
* It will not return if the user is not allowed.
|
||||
*/
|
||||
static void
|
||||
check_perms(MAYBE_UNUSED const struct option_flags *flags)
|
||||
{
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
struct passwd *pampw;
|
||||
bool process_selinux;
|
||||
|
||||
process_selinux = !flags->chroot;
|
||||
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (NULL == pampw) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
fail_exit (EXIT_FAILURE, process_selinux);
|
||||
}
|
||||
|
||||
retval = pam_start ("newusers", pampw->pw_name, &conv, &pamh);
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
fail_exit (EXIT_FAILURE, process_selinux);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
}
|
||||
|
||||
/*
|
||||
* open_files - lock and open the password, group and shadow databases
|
||||
*/
|
||||
@ -1088,8 +1028,6 @@ int main (int argc, char **argv)
|
||||
process_flags (argc, argv, &flags);
|
||||
process_selinux = !flags.chroot;
|
||||
|
||||
check_perms (&flags);
|
||||
|
||||
is_shadow = spw_file_present ();
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
|
||||
46
src/su.c
46
src/su.c
@ -60,7 +60,6 @@
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strcpy/strtcpy.h"
|
||||
@ -94,12 +93,9 @@ static char caller_name[BUFSIZ];
|
||||
static bool change_environment = true;
|
||||
|
||||
#ifdef USE_PAM
|
||||
static char kill_msg[256];
|
||||
static char wait_msg[256];
|
||||
static pam_handle_t *pamh = NULL;
|
||||
static int caught = 0;
|
||||
/* PID of the child, in case it needs to be killed */
|
||||
static pid_t pid_child = 0;
|
||||
static volatile sig_atomic_t caught = 0;
|
||||
static volatile sig_atomic_t timeout = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -115,8 +111,9 @@ static void execve_shell (const char *shellname,
|
||||
char *args[],
|
||||
char *const envp[]);
|
||||
#ifdef USE_PAM
|
||||
static void kill_child(int);
|
||||
static void kill_child(pid_t);
|
||||
static void prepare_pam_close_session (void);
|
||||
static void set_timeout(int);
|
||||
#else /* !USE_PAM */
|
||||
static void die (int);
|
||||
static bool iswheel (const char *);
|
||||
@ -169,16 +166,19 @@ static bool iswheel (const char *username)
|
||||
return is_on_list (grp->gr_mem, username);
|
||||
}
|
||||
#else /* USE_PAM */
|
||||
NORETURN
|
||||
static void
|
||||
kill_child(int)
|
||||
kill_child(pid_t pid_child)
|
||||
{
|
||||
if (0 != pid_child) {
|
||||
(void) kill (-pid_child, SIGKILL);
|
||||
(void) write_full(STDERR_FILENO, kill_msg, strlen(kill_msg));
|
||||
} else {
|
||||
(void) write_full(STDERR_FILENO, wait_msg, strlen(wait_msg));
|
||||
}
|
||||
_exit (255);
|
||||
kill(-pid_child, SIGKILL);
|
||||
fputs(_(" ...killed.\n"), stderr);
|
||||
exit (255);
|
||||
}
|
||||
|
||||
static void
|
||||
set_timeout(int)
|
||||
{
|
||||
timeout = 1;
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
@ -286,6 +286,7 @@ static void prepare_pam_close_session (void)
|
||||
int status;
|
||||
int ret;
|
||||
struct sigaction action;
|
||||
pid_t pid_child;
|
||||
|
||||
/* reset SIGCHLD handling to default */
|
||||
action.sa_handler = SIG_DFL;
|
||||
@ -368,7 +369,7 @@ static void prepare_pam_close_session (void)
|
||||
&& (EINTR == errno)
|
||||
&& (SIGTSTP == caught)) {
|
||||
caught = 0;
|
||||
/* Except for SIGTSTP, which request to
|
||||
/* Except for SIGTSTP, which requests to
|
||||
* stop the child.
|
||||
* We will SIGSTOP ourself on the next
|
||||
* waitpid round.
|
||||
@ -395,21 +396,18 @@ static void prepare_pam_close_session (void)
|
||||
stderr);
|
||||
(void) kill (-pid_child, caught);
|
||||
|
||||
stprintf_a(kill_msg, _(" ...killed.\n"));
|
||||
stprintf_a(wait_msg, _(" ...waiting for child to terminate.\n"));
|
||||
|
||||
/* Any signals other than SIGCHLD and SIGALRM will no longer have any effect,
|
||||
* so it's time to block all of them. */
|
||||
sigfillset (&ourset);
|
||||
if (sigprocmask (SIG_BLOCK, &ourset, NULL) != 0) {
|
||||
fprintf (stderr, _("%s: signal masking malfunction\n"), Prog);
|
||||
kill_child (0);
|
||||
/* Never reach (_exit called). */
|
||||
kill_child(pid_child);
|
||||
/* Never reached (exit called). */
|
||||
}
|
||||
|
||||
/* Send SIGKILL to the child if it doesn't
|
||||
* exit within 2 seconds (after SIGTERM) */
|
||||
(void) signal (SIGALRM, kill_child);
|
||||
(void) signal (SIGALRM, set_timeout);
|
||||
(void) signal (SIGCHLD, catch_signals);
|
||||
(void) alarm (2);
|
||||
|
||||
@ -418,6 +416,10 @@ static void prepare_pam_close_session (void)
|
||||
|
||||
while (0 == waitpid (pid_child, &status, WNOHANG)) {
|
||||
sigsuspend (&ourset);
|
||||
if (timeout) {
|
||||
kill_child(pid_child);
|
||||
/* Never reached (exit called). */
|
||||
}
|
||||
}
|
||||
pid_child = 0;
|
||||
|
||||
|
||||
@ -23,11 +23,6 @@
|
||||
#include <libgen.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
# ifdef USE_PAM
|
||||
# include "pam_defs.h"
|
||||
# endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
#include <paths.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
@ -114,6 +109,7 @@ static const char *def_shell = "/bin/bash";
|
||||
static const char *def_template = SKEL_DIR;
|
||||
static const char *def_usrtemplate = USRSKELDIR;
|
||||
static const char *def_create_mail_spool = "yes";
|
||||
static const char *def_btrfs_subvolume_home = "no";
|
||||
static const char *def_log_init = "yes";
|
||||
|
||||
static long def_inactive = -1;
|
||||
@ -222,6 +218,7 @@ static bool home_added = false;
|
||||
#define DSKEL "SKEL"
|
||||
#define DUSRSKEL "USRSKEL"
|
||||
#define DCREATE_MAIL_SPOOL "CREATE_MAIL_SPOOL"
|
||||
#define DBTRFS_SUBVOLUME_HOME "BTRFS_SUBVOLUME_HOME"
|
||||
#define DLOG_INIT "LOG_INIT"
|
||||
|
||||
/* local function prototypes */
|
||||
@ -456,6 +453,7 @@ get_defaults(const struct option_flags *flags)
|
||||
def_usrtemplate = xstrdup(ccp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create by default user mail spool or not ?
|
||||
*/
|
||||
@ -466,6 +464,15 @@ get_defaults(const struct option_flags *flags)
|
||||
def_create_mail_spool = xstrdup(ccp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create home directories as Btrfs subvolumes by default?
|
||||
*/
|
||||
else if (streq(buf, DBTRFS_SUBVOLUME_HOME)) {
|
||||
if (streq(ccp, ""))
|
||||
ccp = "no";
|
||||
def_btrfs_subvolume_home = xstrdup(ccp);
|
||||
}
|
||||
|
||||
/*
|
||||
* By default do we add the user to the lastlog and faillog databases ?
|
||||
*/
|
||||
@ -500,6 +507,7 @@ static void show_defaults (void)
|
||||
printf ("SKEL=%s\n", def_template);
|
||||
printf ("USRSKEL=%s\n", def_usrtemplate);
|
||||
printf ("CREATE_MAIL_SPOOL=%s\n", def_create_mail_spool);
|
||||
printf ("BTRFS_SUBVOLUME_HOME=%s\n", def_btrfs_subvolume_home);
|
||||
printf ("LOG_INIT=%s\n", def_log_init);
|
||||
}
|
||||
|
||||
@ -523,6 +531,7 @@ set_defaults(void)
|
||||
bool out_skel = false;
|
||||
bool out_usrskel = false;
|
||||
bool out_create_mail_spool = false;
|
||||
bool out_btrfs_subvolume_home = false;
|
||||
bool out_log_init = false;
|
||||
char buf[1024];
|
||||
char *new_file = NULL;
|
||||
@ -639,6 +648,11 @@ set_defaults(void)
|
||||
DCREATE_MAIL_SPOOL "=%s\n",
|
||||
def_create_mail_spool);
|
||||
out_create_mail_spool = true;
|
||||
} else if (!out_btrfs_subvolume_home && streq(buf, DBTRFS_SUBVOLUME_HOME)) {
|
||||
fprintf(ofp,
|
||||
DBTRFS_SUBVOLUME_HOME "=%s\n",
|
||||
def_btrfs_subvolume_home);
|
||||
out_btrfs_subvolume_home = true;
|
||||
} else if (!out_log_init && streq(buf, DLOG_INIT)) {
|
||||
fprintf(ofp, DLOG_INIT "=%s\n", def_log_init);
|
||||
out_log_init = true;
|
||||
@ -673,6 +687,8 @@ set_defaults(void)
|
||||
|
||||
if (!out_create_mail_spool)
|
||||
fprintf (ofp, DCREATE_MAIL_SPOOL "=%s\n", def_create_mail_spool);
|
||||
if (!out_btrfs_subvolume_home)
|
||||
fprintf (ofp, DBTRFS_SUBVOLUME_HOME "=%s\n", def_btrfs_subvolume_home);
|
||||
if (!out_log_init)
|
||||
fprintf (ofp, DLOG_INIT "=%s\n", def_log_init);
|
||||
/*
|
||||
@ -1431,6 +1447,9 @@ static void process_flags (int argc, char **argv, struct option_flags *flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (!subvolflg && strcaseeq(def_btrfs_subvolume_home, "yes"))
|
||||
subvolflg = true;
|
||||
|
||||
if (!gflg && !Nflg && !Uflg) {
|
||||
/* Get the settings from login.defs */
|
||||
Uflg = getdef_bool ("USERGROUPS_ENAB");
|
||||
@ -2430,13 +2449,6 @@ static void check_uid_range(int rflg, uid_t user_id)
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
uid_t uid_min;
|
||||
uid_t uid_max;
|
||||
@ -2500,42 +2512,6 @@ int main (int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
{
|
||||
struct passwd *pampw;
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (pampw == NULL && getuid ()) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
fail_exit (1, process_selinux);
|
||||
}
|
||||
|
||||
retval = pam_start (Prog, pampw?pampw->pw_name:"root", &conv, &pamh);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
fail_exit (1, process_selinux);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
/*
|
||||
* See if we are messing with the defaults file, or creating
|
||||
* a new user.
|
||||
@ -2684,9 +2660,9 @@ int main (int argc, char **argv)
|
||||
if (mflg) {
|
||||
create_home (&flags);
|
||||
if (home_added) {
|
||||
copy_tree (def_template, prefix_user_home, false, true,
|
||||
copy_tree (def_template, prefix_user_home, false,
|
||||
(uid_t)-1, user_id, (gid_t)-1, user_gid);
|
||||
copy_tree (def_usrtemplate, prefix_user_home, false, true,
|
||||
copy_tree (def_usrtemplate, prefix_user_home, false,
|
||||
(uid_t)-1, user_id, (gid_t)-1, user_gid);
|
||||
} else {
|
||||
fprintf (stderr,
|
||||
|
||||
@ -20,11 +20,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "groupio.h"
|
||||
@ -909,12 +904,6 @@ int main (int argc, char **argv)
|
||||
{
|
||||
bool errors = false; /* Error in the removal of the home directory */
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
struct option_flags flags = {.chroot = false, .prefix = false};
|
||||
bool process_selinux;
|
||||
|
||||
@ -1001,42 +990,6 @@ int main (int argc, char **argv)
|
||||
usage (E_USAGE);
|
||||
}
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
{
|
||||
struct passwd *pampw;
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (pampw == NULL) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
|
||||
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
is_shadow_pwd = spw_file_present ();
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
|
||||
101
src/usermod.c
101
src/usermod.c
@ -21,13 +21,9 @@
|
||||
#include <lastlog.h>
|
||||
#endif /* ENABLE_LASTLOG */
|
||||
#include <pwd.h>
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/stat.h>
|
||||
@ -97,6 +93,7 @@
|
||||
#define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */
|
||||
#define E_SUB_GID_UPDATE 18 /* can't update the subordinate gid file */
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
#define E_PASSWORDLESS 20 /* would result in a passwordless account */
|
||||
|
||||
#define VALID(s) (!strpbrk(s, ":\n"))
|
||||
|
||||
@ -437,7 +434,8 @@ usage (int status)
|
||||
* update encrypted password string (for both shadow and non-shadow
|
||||
* passwords)
|
||||
*/
|
||||
static char *new_pw_passwd (char *pw_pass)
|
||||
static char *
|
||||
new_pw_passwd(char *pw_pass, bool process_selinux)
|
||||
{
|
||||
if (Lflg && ('!' != pw_pass[0])) {
|
||||
#ifdef WITH_AUDIT
|
||||
@ -452,7 +450,7 @@ static char *new_pw_passwd (char *pw_pass)
|
||||
_("%s: unlocking the user's password would result in a passwordless account.\n"
|
||||
"You should set a password with usermod -p to unlock this user's password.\n"),
|
||||
Prog);
|
||||
return pw_pass;
|
||||
fail_exit(E_PASSWORDLESS, process_selinux);
|
||||
}
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
@ -507,7 +505,7 @@ static void new_pwent (struct passwd *pwent, bool process_selinux)
|
||||
*/
|
||||
if ( (!is_shadow_pwd)
|
||||
|| !streq(pwent->pw_passwd, SHADOW_PASSWD_STRING)) {
|
||||
pwent->pw_passwd = new_pw_passwd (pwent->pw_passwd);
|
||||
pwent->pw_passwd = new_pw_passwd(pwent->pw_passwd, process_selinux);
|
||||
}
|
||||
|
||||
if (uflg) {
|
||||
@ -622,7 +620,7 @@ static void new_spent (struct spwd *spent, bool process_selinux)
|
||||
* + there were already both entries
|
||||
* + aging has been requested
|
||||
*/
|
||||
spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp);
|
||||
spent->sp_pwdp = new_pw_passwd(spent->sp_pwdp, process_selinux);
|
||||
|
||||
if (pflg) {
|
||||
spent->sp_lstchg = gettime () / DAY;
|
||||
@ -1388,6 +1386,48 @@ process_flags(int argc, char **argv, struct option_flags *flags)
|
||||
}
|
||||
#endif /* WITH_SELINUX */
|
||||
|
||||
if (user_newid == user_id) {
|
||||
uflg = false;
|
||||
oflg = false;
|
||||
}
|
||||
if (user_newgid == user_gid) {
|
||||
gflg = false;
|
||||
}
|
||||
if ( (NULL != user_newshell)
|
||||
&& streq(user_newshell, user_shell)) {
|
||||
sflg = false;
|
||||
}
|
||||
if (streq(user_newname, user_name)) {
|
||||
lflg = false;
|
||||
}
|
||||
if (user_newinactive == user_inactive) {
|
||||
fflg = false;
|
||||
}
|
||||
if (user_newexpire == user_expire) {
|
||||
eflg = false;
|
||||
}
|
||||
if ( (NULL != user_newhome)
|
||||
&& streq(user_newhome, user_home)) {
|
||||
dflg = false;
|
||||
mflg = false;
|
||||
}
|
||||
if ( (NULL != user_newcomment)
|
||||
&& streq(user_newcomment, user_comment)) {
|
||||
cflg = false;
|
||||
}
|
||||
|
||||
if (!(Uflg || uflg || sflg || pflg || mflg || Lflg ||
|
||||
lflg || Gflg || gflg || fflg || eflg || dflg || cflg
|
||||
#ifdef ENABLE_SUBIDS
|
||||
|| vflg || Vflg || wflg || Wflg
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
#ifdef WITH_SELINUX
|
||||
|| Zflg
|
||||
#endif /* WITH_SELINUX */
|
||||
)) {
|
||||
exit (E_SUCCESS);
|
||||
}
|
||||
|
||||
if (!is_shadow_pwd && (eflg || fflg)) {
|
||||
fprintf (stderr,
|
||||
_("%s: shadow passwords required for -e and -f\n"),
|
||||
@ -1850,7 +1890,6 @@ static void move_home (bool process_selinux)
|
||||
#endif
|
||||
|
||||
if (copy_tree (prefix_user_home, prefix_user_newhome, true,
|
||||
true,
|
||||
user_id,
|
||||
uflg ? user_newid : (uid_t)-1,
|
||||
user_gid,
|
||||
@ -2128,12 +2167,6 @@ static void move_mailbox (void)
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
struct option_flags flags = {.chroot = false, .prefix = false};
|
||||
bool process_selinux;
|
||||
|
||||
@ -2182,42 +2215,6 @@ int main (int argc, char **argv)
|
||||
exit (E_USER_BUSY);
|
||||
}
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
{
|
||||
struct passwd *pampw;
|
||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||
if (pampw == NULL) {
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == retval) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS != retval) {
|
||||
fprintf (stderr, _("%s: PAM: %s\n"),
|
||||
Prog, pam_strerror (pamh, retval));
|
||||
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
exit (1);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
#ifdef WITH_TCB
|
||||
if (shadowtcb_set_user (user_name) == SHADOWTCB_FAILURE) {
|
||||
exit (E_PW_UPDATE);
|
||||
|
||||
38
src/vipw.c
38
src/vipw.c
@ -43,6 +43,7 @@
|
||||
#endif /* WITH_TCB */
|
||||
#include "shadowlog.h"
|
||||
#include "sssd.h"
|
||||
#include "fs/mkstemp/fmkomstemp.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
@ -72,7 +73,7 @@ static bool tcb_mode = false;
|
||||
|
||||
/* local function prototypes */
|
||||
static void usage (int status);
|
||||
static int create_backup_file (FILE *, const char *, struct stat *);
|
||||
static int create_backup_file (FILE *, char *, struct stat *);
|
||||
static void vipwexit (const char *msg, int syserr, int ret);
|
||||
static void vipwedit (const char *, int (*)(void), int (*)(bool));
|
||||
|
||||
@ -103,16 +104,13 @@ static void usage (int status)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static int create_backup_file (FILE * fp, const char *backup, struct stat *sb)
|
||||
static int create_backup_file (FILE * fp, char *backup, struct stat *sb)
|
||||
{
|
||||
struct utimbuf ub;
|
||||
FILE *bkfp;
|
||||
int c;
|
||||
mode_t mask;
|
||||
|
||||
mask = umask (077);
|
||||
bkfp = fopen (backup, "w");
|
||||
(void) umask (mask);
|
||||
bkfp = fmkomstemp(backup, 0, 0600);
|
||||
if (NULL == bkfp) {
|
||||
return -1;
|
||||
}
|
||||
@ -134,16 +132,18 @@ static int create_backup_file (FILE * fp, const char *backup, struct stat *sb)
|
||||
unlink (backup);
|
||||
return -1;
|
||||
}
|
||||
if (fclose (bkfp) != 0) {
|
||||
unlink (backup);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ub.actime = sb->st_atime;
|
||||
ub.modtime = sb->st_mtime;
|
||||
if ( (utime (backup, &ub) != 0)
|
||||
|| (chmod (backup, sb->st_mode) != 0)
|
||||
|| (chown (backup, sb->st_uid, sb->st_gid) != 0)) {
|
||||
|| (fchown(fileno(bkfp), sb->st_uid, sb->st_gid) != 0)
|
||||
|| (fchmod(fileno(bkfp), sb->st_mode) != 0)) {
|
||||
fclose(bkfp);
|
||||
unlink (backup);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fclose (bkfp) != 0) {
|
||||
unlink (backup);
|
||||
return -1;
|
||||
}
|
||||
@ -217,11 +217,11 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool))
|
||||
vipwexit (_("failed to drop privileges"), errno, 1);
|
||||
}
|
||||
stprintf_a(fileedit,
|
||||
TCB_DIR "/" SHADOWTCB_SCRATCHDIR "/.vipw.shadow.%s",
|
||||
user);
|
||||
TCB_DIR "/" SHADOWTCB_SCRATCHDIR "/.%s.shadow.%s.XXXXXX",
|
||||
Prog, user);
|
||||
} else {
|
||||
#endif /* WITH_TCB */
|
||||
stprintf_a(fileedit, "%s.edit", file);
|
||||
stprintf_a(fileedit, "/etc/.%s.XXXXXX", Prog);
|
||||
#ifdef WITH_TCB
|
||||
}
|
||||
#endif /* WITH_TCB */
|
||||
@ -291,6 +291,9 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool))
|
||||
|
||||
orig_pgrp = tcgetpgrp(STDIN_FILENO);
|
||||
|
||||
/* set SIGCHLD to default for waitpid */
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
pid = fork ();
|
||||
if (-1 == pid) {
|
||||
vipwexit ("fork", 1, 1);
|
||||
@ -338,9 +341,6 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool))
|
||||
sigprocmask(SIG_BLOCK, &mask, &omask);
|
||||
}
|
||||
|
||||
/* set SIGCHLD to default for waitpid */
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
for (;;) {
|
||||
pid = waitpid (pid, &status, WUNTRACED);
|
||||
if ((pid != -1) && (WIFSTOPPED (status) != 0)) {
|
||||
@ -426,7 +426,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool))
|
||||
if (stat (file, &st1) != 0) {
|
||||
vipwexit (_("failed to stat edited file"), errno, 1);
|
||||
}
|
||||
to_rename = aprintf("%s+", file);
|
||||
to_rename = aprintf("%s,XXXXXX", file);
|
||||
if (to_rename == NULL)
|
||||
vipwexit (_("aprintf() failed"), errno, 1);
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ class UnixObject(object):
|
||||
if len(o) != 2 or not isinstance(o[0], int) or not isinstance(o[1], str):
|
||||
raise NotImplementedError(f"Unable to compare {type(o)} with {self.__class__}")
|
||||
|
||||
(id, name) = o
|
||||
id, name = o
|
||||
return id == self.id and name == self.name
|
||||
elif isinstance(o, UnixObject):
|
||||
# Fallback to identity comparison
|
||||
@ -388,8 +388,8 @@ class GShadowEntry(object):
|
||||
self,
|
||||
name: str | None,
|
||||
password: str | None,
|
||||
administrators: str | None,
|
||||
members: str | None,
|
||||
administrators: list[str],
|
||||
members: list[str],
|
||||
) -> None:
|
||||
self.name: str | None = name
|
||||
"""
|
||||
@ -401,18 +401,18 @@ class GShadowEntry(object):
|
||||
Group password.
|
||||
"""
|
||||
|
||||
self.administrators: str | None = administrators
|
||||
self.administrators: list[str] = administrators
|
||||
"""
|
||||
Group administrators.
|
||||
"""
|
||||
|
||||
self.members: str | None = members
|
||||
self.members: list[str] = members
|
||||
"""
|
||||
Group members.
|
||||
"""
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"({self.name}:{self.password}:{self.administrators}:" f"{self.members})"
|
||||
return f"({self.name}:{self.password}:" f"{self.administrators}:" f"{self.members})"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return str(self)
|
||||
@ -422,7 +422,7 @@ class GShadowEntry(object):
|
||||
return cls(
|
||||
name=d.get("group_name", None),
|
||||
password=d.get("password", None),
|
||||
administrators=d.get("administrators", None),
|
||||
administrators=d.get("administrators", []),
|
||||
members=d.get("members", []),
|
||||
)
|
||||
|
||||
|
||||
@ -69,3 +69,63 @@ def test_groupmod__u_option_empty_string_clears_members(shadow: Shadow):
|
||||
assert gshadow_entry is not None, "Group should be found"
|
||||
assert gshadow_entry.name == "tgroup", "Incorrect groupname"
|
||||
assert not gshadow_entry.members, "Group should have no members"
|
||||
|
||||
|
||||
@pytest.mark.topology(KnownTopology.Shadow)
|
||||
def test_groupmod__u_option_with_user_list(shadow: Shadow):
|
||||
"""
|
||||
:title: Test groupmod -U option with user list to set group membership
|
||||
:setup:
|
||||
1. Create three test users
|
||||
2. Create test group
|
||||
:steps:
|
||||
1. Set group membership to all three users using groupmod -U
|
||||
2. Verify all three users are members in group and gshadow entry
|
||||
3. Modify group membership to only two users using groupmod -U
|
||||
4. Verify updated membership in group and gshadow entries
|
||||
:expectedresults:
|
||||
1. Initial groupmod -U command sets membership correctly for all three users
|
||||
2. group and gshadow entries show correct membership
|
||||
3. Second groupmod -U command updates membership correctly
|
||||
4. Updated group and gshadow entries reflect new membership
|
||||
:customerscenario: False
|
||||
"""
|
||||
shadow.useradd("tuser1")
|
||||
shadow.useradd("tuser2")
|
||||
shadow.useradd("tuser3")
|
||||
shadow.groupadd("tgroup")
|
||||
shadow.groupmod("-U tuser1,tuser2,tuser3 tgroup")
|
||||
|
||||
group_entry = shadow.tools.getent.group("tgroup")
|
||||
assert group_entry is not None, "Group should be found"
|
||||
assert group_entry.name == "tgroup", "Incorrect groupname"
|
||||
assert len(group_entry.members) == 3, f"Group should have 3 members, but has {len(group_entry.members)}"
|
||||
assert "tuser1" in group_entry.members, "tuser1 should be a member of tgroup"
|
||||
assert "tuser2" in group_entry.members, "tuser2 should be a member of tgroup"
|
||||
assert "tuser3" in group_entry.members, "tuser3 should be a member of tgroup"
|
||||
|
||||
if shadow.host.features["gshadow"]:
|
||||
gshadow_entry = shadow.tools.getent.gshadow("tgroup")
|
||||
assert gshadow_entry is not None, "Group should be found"
|
||||
assert gshadow_entry.name == "tgroup", "Incorrect groupname"
|
||||
assert len(gshadow_entry.members) == 3, f"Group should have 3 members, but has {len(gshadow_entry.members)}"
|
||||
assert "tuser1" in gshadow_entry.members, "tuser1 should be a member of tgroup"
|
||||
assert "tuser2" in gshadow_entry.members, "tuser2 should be a member of tgroup"
|
||||
assert "tuser3" in gshadow_entry.members, "tuser3 should be a member of tgroup"
|
||||
|
||||
shadow.groupmod("-U tuser1,tuser2 tgroup")
|
||||
|
||||
group_entry = shadow.tools.getent.group("tgroup")
|
||||
assert group_entry is not None, "Group should be found"
|
||||
assert group_entry.name == "tgroup", "Incorrect groupname"
|
||||
assert len(group_entry.members) == 2, f"Group should have 2 members, but has {len(group_entry.members)}"
|
||||
assert "tuser1" in group_entry.members, "tuser1 should be a member of tgroup"
|
||||
assert "tuser2" in group_entry.members, "tuser2 should be a member of tgroup"
|
||||
|
||||
if shadow.host.features["gshadow"]:
|
||||
gshadow_entry = shadow.tools.getent.gshadow("tgroup")
|
||||
assert gshadow_entry is not None, "Group should be found"
|
||||
assert gshadow_entry.name == "tgroup", "Incorrect groupname"
|
||||
assert len(gshadow_entry.members) == 2, f"Group should have 2 members, but has {len(gshadow_entry.members)}"
|
||||
assert "tuser1" in gshadow_entry.members, "tuser1 should be a member of tgroup"
|
||||
assert "tuser2" in gshadow_entry.members, "tuser2 should be a member of tgroup"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user