New upstream version 4.12.2+dfsg1

This commit is contained in:
Balint Reczey
2022-08-20 18:17:16 +02:00
parent 0c04b92a9a
commit 675b462b64
595 changed files with 61746 additions and 60480 deletions
+15 -12
View File
@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -92,13 +92,14 @@ host_triplet = @host@
subdir = libmisc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
$(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
@@ -245,8 +246,6 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
$(top_srcdir)/ylwrap getdate.c
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -263,6 +262,8 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -274,8 +275,10 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
ECONF_CPPFLAGS = @ECONF_CPPFLAGS@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
@@ -349,6 +352,7 @@ VENDORDIR = @VENDORDIR@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
XGETTEXT_015 = @XGETTEXT_015@
XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XMLCATALOG = @XMLCATALOG@
XML_CATALOG_FILE = @XML_CATALOG_FILE@
XSLTPROC = @XSLTPROC@
@@ -632,7 +636,6 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
+1 -1
View File
@@ -14,7 +14,7 @@ static bool path_exists(const char *p)
static const char *btrfs_cmd(void)
{
const char *btrfs_paths[] = {"/sbin/btrfs",
const char *const btrfs_paths[] = {"/sbin/btrfs",
"/bin/btrfs", "/usr/sbin/btrfs", "/usr/bin/btrfs", NULL};
const char *p;
int i;
+107 -139
View File
@@ -17,6 +17,112 @@
#include "defines.h"
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
static int chown_tree_at (int at_fd,
const char *path,
uid_t old_uid,
uid_t new_uid,
gid_t old_gid,
gid_t new_gid)
{
DIR *dir;
const struct dirent *ent;
struct stat dir_sb;
int dir_fd, rc = 0;
dir_fd = openat (at_fd, path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
if (dir_fd < 0) {
return -1;
}
dir = fdopendir (dir_fd);
if (!dir) {
(void) close (dir_fd);
return -1;
}
/*
* Open the directory and read each entry. Every entry is tested
* to see if it is a directory, and if so this routine is called
* recursively. If not, it is checked to see if an ownership
* shall be changed.
*/
while ((ent = readdir (dir))) {
uid_t tmpuid = (uid_t) -1;
gid_t tmpgid = (gid_t) -1;
struct stat ent_sb;
/*
* Skip the "." and ".." entries
*/
if ( (strcmp (ent->d_name, ".") == 0)
|| (strcmp (ent->d_name, "..") == 0)) {
continue;
}
rc = fstatat (dirfd(dir), ent->d_name, &ent_sb, AT_SYMLINK_NOFOLLOW);
if (rc < 0) {
break;
}
if (S_ISDIR (ent_sb.st_mode)) {
/*
* Do the entire subdirectory.
*/
rc = chown_tree_at (dirfd(dir), ent->d_name, old_uid, new_uid, old_gid, new_gid);
if (0 != rc) {
break;
}
}
/*
* By default, the IDs are not changed (-1).
*
* If the file is not owned by the user, the owner is not
* changed.
*
* If the file is not group-owned by the group, the
* group-owner is not changed.
*/
if (((uid_t) -1 == old_uid) || (ent_sb.st_uid == old_uid)) {
tmpuid = new_uid;
}
if (((gid_t) -1 == old_gid) || (ent_sb.st_gid == old_gid)) {
tmpgid = new_gid;
}
if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) {
rc = fchownat (dirfd(dir), ent->d_name, tmpuid, tmpgid, AT_SYMLINK_NOFOLLOW);
if (0 != rc) {
break;
}
}
}
/*
* Now do the root of the tree
*/
if ((0 == rc) && (fstat (dirfd(dir), &dir_sb) == 0)) {
uid_t tmpuid = (uid_t) -1;
gid_t tmpgid = (gid_t) -1;
if (((uid_t) -1 == old_uid) || (dir_sb.st_uid == old_uid)) {
tmpuid = new_uid;
}
if (((gid_t) -1 == old_gid) || (dir_sb.st_gid == old_gid)) {
tmpgid = new_gid;
}
if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) {
rc = fchown (dirfd(dir), tmpuid, tmpgid);
}
} else {
rc = -1;
}
(void) closedir (dir);
return rc;
}
/*
* chown_tree - change ownership of files in a directory tree
*
@@ -36,143 +142,5 @@ int chown_tree (const char *root,
gid_t old_gid,
gid_t new_gid)
{
char *new_name;
size_t new_name_len;
int rc = 0;
struct DIRECT *ent;
struct stat sb;
DIR *dir;
new_name = malloc (1024);
if (NULL == new_name) {
return -1;
}
new_name_len = 1024;
/*
* Make certain the directory exists. This routine is called
* directly by the invoker, or recursively.
*/
if (access (root, F_OK) != 0) {
free (new_name);
return -1;
}
/*
* Open the directory and read each entry. Every entry is tested
* to see if it is a directory, and if so this routine is called
* recursively. If not, it is checked to see if an ownership
* shall be changed.
*/
dir = opendir (root);
if (NULL == dir) {
free (new_name);
return -1;
}
while ((ent = readdir (dir))) {
size_t ent_name_len;
uid_t tmpuid = (uid_t) -1;
gid_t tmpgid = (gid_t) -1;
/*
* Skip the "." and ".." entries
*/
if ( (strcmp (ent->d_name, ".") == 0)
|| (strcmp (ent->d_name, "..") == 0)) {
continue;
}
/*
* Make the filename for both the source and the
* destination files.
*/
ent_name_len = strlen (root) + strlen (ent->d_name) + 2;
if (ent_name_len > new_name_len) {
/*@only@*/char *tmp = realloc (new_name, ent_name_len);
if (NULL == tmp) {
rc = -1;
break;
}
new_name = tmp;
new_name_len = ent_name_len;
}
(void) snprintf (new_name, new_name_len, "%s/%s", root, ent->d_name);
/* Don't follow symbolic links! */
if (LSTAT (new_name, &sb) == -1) {
continue;
}
if (S_ISDIR (sb.st_mode) && !S_ISLNK (sb.st_mode)) {
/*
* Do the entire subdirectory.
*/
rc = chown_tree (new_name, old_uid, new_uid,
old_gid, new_gid);
if (0 != rc) {
break;
}
}
#ifndef HAVE_LCHOWN
/* don't use chown (follows symbolic links!) */
if (S_ISLNK (sb.st_mode)) {
continue;
}
#endif
/*
* By default, the IDs are not changed (-1).
*
* If the file is not owned by the user, the owner is not
* changed.
*
* If the file is not group-owned by the group, the
* group-owner is not changed.
*/
if (((uid_t) -1 == old_uid) || (sb.st_uid == old_uid)) {
tmpuid = new_uid;
}
if (((gid_t) -1 == old_gid) || (sb.st_gid == old_gid)) {
tmpgid = new_gid;
}
if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) {
rc = LCHOWN (new_name, tmpuid, tmpgid);
if (0 != rc) {
break;
}
}
}
free (new_name);
(void) closedir (dir);
/*
* Now do the root of the tree
*/
if ((0 == rc) && (stat (root, &sb) == 0)) {
uid_t tmpuid = (uid_t) -1;
gid_t tmpgid = (gid_t) -1;
if (((uid_t) -1 == old_uid) || (sb.st_uid == old_uid)) {
tmpuid = new_uid;
}
if (((gid_t) -1 == old_gid) || (sb.st_gid == old_gid)) {
tmpgid = new_gid;
}
if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) {
rc = LCHOWN (root, tmpuid, tmpgid);
}
} else {
rc = -1;
}
return rc;
return chown_tree_at (AT_FDCWD, root, old_uid, new_uid, old_gid, new_gid);
}
-3
View File
@@ -16,9 +16,6 @@
#ident "$Id$"
/* local function prototypes */
static bool is_listed (const char *cfgin, const char *tty, bool def);
/*
* This is now rather generic function which decides if "tty" is listed
* under "cfgin" in config (directly or indirectly). Fallback to default if
+277 -126
View File
@@ -47,42 +47,43 @@ struct link_name {
};
static /*@exposed@*/struct link_name *links;
static int copy_entry (const char *src, const char *dst,
struct path_info {
const char *full_path;
int dirfd;
const char *name;
};
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 char *src, const char *dst,
static int copy_dir (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
#ifdef S_IFLNK
static /*@null@*/char *readlink_malloc (const char *filename);
static int copy_symlink (const char *src, const char *dst,
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
unused bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
#endif /* S_IFLNK */
static int copy_hardlink (const char *dst,
static int copy_hardlink (const struct path_info *dst,
unused bool reset_selinux,
struct link_name *lp);
static int copy_special (const char *src, const char *dst,
static int copy_special (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
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 char *src, const char *dst,
static int copy_file (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
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 chown_if_needed (const char *dst, const struct stat *statp,
static int chownat_if_needed (const struct path_info *dst, const struct stat *statp,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static int lchown_if_needed (const char *dst, const struct stat *statp,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
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);
@@ -91,7 +92,8 @@ static int fchown_if_needed (int fdst, const struct stat *statp,
/*
* error_acl - format the error messages for the ACL and EQ libraries.
*/
static void error_acl (struct error_context *ctx, const char *fmt, ...)
format_attr(printf, 2, 3)
static void error_acl (unused struct error_context *ctx, const char *fmt, ...)
{
va_list ap;
FILE *shadow_logfd = log_get_logfd();
@@ -113,10 +115,61 @@ static void error_acl (struct error_context *ctx, const char *fmt, ...)
}
static struct error_context ctx = {
error_acl
error_acl, NULL, NULL
};
#endif /* WITH_ACL || WITH_ATTR */
#ifdef WITH_ACL
static int perm_copy_path(const struct path_info *src,
const struct path_info *dst,
struct error_context *errctx)
{
int src_fd, dst_fd, ret;
src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
if (src_fd < 0) {
return -1;
}
dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
if (dst_fd < 0) {
(void) close (src_fd);
return -1;
}
ret = perm_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, errctx);
(void) close (src_fd);
(void) close (dst_fd);
return ret;
}
#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_CLOEXEC);
if (src_fd < 0) {
return -1;
}
dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | 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
*/
@@ -189,51 +242,36 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
return NULL;
}
/*
* copy_tree - copy files in a directory tree
*
* 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
* new_uid is set to -1, no ownership will be changed.
*
* The same logic applies for the group-ownership and
* old_gid/new_gid.
*/
int copy_tree (const char *src_root, const char *dst_root,
static int copy_tree_impl (const struct path_info *src, const struct path_info *dst,
bool copy_root, bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
int err = 0;
int dst_fd, src_fd, err = 0;
bool set_orig = false;
struct DIRECT *ent;
const struct dirent *ent;
DIR *dir;
if (copy_root) {
struct stat sb;
if (access (dst_root, F_OK) == 0) {
if ( fstatat (dst->dirfd, dst->name, &sb, 0) == 0
|| errno != ENOENT) {
return -1;
}
if (LSTAT (src_root, &sb) == -1) {
if (fstatat (src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
return -1;
}
if (!S_ISDIR (sb.st_mode)) {
fprintf (log_get_logfd(),
"%s: %s is not a directory",
log_get_progname(), src_root);
log_get_progname(), src->full_path);
return -1;
}
return copy_entry (src_root, dst_root, reset_selinux,
return copy_entry (src, dst, reset_selinux,
old_uid, new_uid, old_gid, new_gid);
}
@@ -243,8 +281,14 @@ int copy_tree (const char *src_root, const char *dst_root,
* target is created. It assumes the target directory exists.
*/
if ( (access (src_root, F_OK) != 0)
|| (access (dst_root, F_OK) != 0)) {
src_fd = openat (src->dirfd, src->name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
if (src_fd < 0) {
return -1;
}
dst_fd = openat (dst->dirfd, dst->name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
if (dst_fd < 0) {
(void) close (src_fd);
return -1;
}
@@ -255,14 +299,16 @@ int copy_tree (const char *src_root, const char *dst_root,
* regular files (and directories ...) are copied, and no file
* is made set-ID.
*/
dir = opendir (src_root);
dir = fdopendir (src_fd);
if (NULL == dir) {
(void) close (src_fd);
(void) close (dst_fd);
return -1;
}
if (src_orig == NULL) {
src_orig = src_root;
dst_orig = dst_root;
src_orig = src->full_path;
dst_orig = dst->full_path;
set_orig = true;
}
while ((0 == err) && (ent = readdir (dir)) != NULL) {
@@ -275,8 +321,8 @@ int copy_tree (const char *src_root, const char *dst_root,
char *dst_name;
size_t src_len = strlen (ent->d_name) + 2;
size_t dst_len = strlen (ent->d_name) + 2;
src_len += strlen (src_root);
dst_len += strlen (dst_root);
src_len += strlen (src->full_path);
dst_len += strlen (dst->full_path);
src_name = (char *) malloc (src_len);
dst_name = (char *) malloc (dst_len);
@@ -288,12 +334,22 @@ int copy_tree (const char *src_root, const char *dst_root,
* Build the filename for both the source and
* the destination files.
*/
(void) snprintf (src_name, src_len, "%s/%s",
src_root, ent->d_name);
(void) snprintf (dst_name, dst_len, "%s/%s",
dst_root, ent->d_name);
struct path_info src_entry, dst_entry;
err = copy_entry (src_name, dst_name,
(void) snprintf (src_name, src_len, "%s/%s",
src->full_path, ent->d_name);
(void) snprintf (dst_name, dst_len, "%s/%s",
dst->full_path, ent->d_name);
src_entry.full_path = src_name;
src_entry.dirfd = dirfd(dir);
src_entry.name = ent->d_name;
dst_entry.full_path = dst_name;
dst_entry.dirfd = dst_fd;
dst_entry.name = ent->d_name;
err = copy_entry (&src_entry, &dst_entry,
reset_selinux,
old_uid, new_uid,
old_gid, new_gid);
@@ -307,6 +363,7 @@ int copy_tree (const char *src_root, const char *dst_root,
}
}
(void) closedir (dir);
(void) close (dst_fd);
if (set_orig) {
src_orig = NULL;
@@ -353,7 +410,7 @@ int copy_tree (const char *src_root, const char *dst_root,
* old_gid) will be modified, unless old_uid (resp. old_gid) is set
* to -1.
*/
static int copy_entry (const char *src, const char *dst,
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)
@@ -361,32 +418,32 @@ static int copy_entry (const char *src, const char *dst,
int err = 0;
struct stat sb;
struct link_name *lp;
struct timeval mt[2];
struct timespec mt[2];
if (LSTAT (src, &sb) == -1) {
if (fstatat(src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
/* If we cannot stat the file, do not care. */
} else {
#ifdef HAVE_STRUCT_STAT_ST_ATIM
mt[0].tv_sec = sb.st_atim.tv_sec;
mt[0].tv_usec = sb.st_atim.tv_nsec / 1000;
mt[0].tv_nsec = sb.st_atim.tv_nsec;
#else /* !HAVE_STRUCT_STAT_ST_ATIM */
mt[0].tv_sec = sb.st_atime;
# ifdef HAVE_STRUCT_STAT_ST_ATIMENSEC
mt[0].tv_usec = sb.st_atimensec / 1000;
mt[0].tv_nsec = sb.st_atimensec;
# else /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
mt[0].tv_usec = 0;
mt[0].tv_nsec = 0;
# endif /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
#endif /* !HAVE_STRUCT_STAT_ST_ATIM */
#ifdef HAVE_STRUCT_STAT_ST_MTIM
mt[1].tv_sec = sb.st_mtim.tv_sec;
mt[1].tv_usec = sb.st_mtim.tv_nsec / 1000;
mt[1].tv_nsec = sb.st_mtim.tv_nsec;
#else /* !HAVE_STRUCT_STAT_ST_MTIM */
mt[1].tv_sec = sb.st_mtime;
# ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC
mt[1].tv_usec = sb.st_mtimensec / 1000;
mt[1].tv_nsec = sb.st_mtimensec;
# else /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
mt[1].tv_usec = 0;
mt[1].tv_nsec = 0;
# endif /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
#endif /* !HAVE_STRUCT_STAT_ST_MTIM */
@@ -395,7 +452,6 @@ static int copy_entry (const char *src, const char *dst,
old_uid, new_uid, old_gid, new_gid);
}
#ifdef S_IFLNK
/*
* Copy any symbolic links
*/
@@ -404,13 +460,12 @@ static int copy_entry (const char *src, const char *dst,
err = copy_symlink (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
#endif /* S_IFLNK */
/*
* See if this is a previously copied link
*/
else if ((lp = check_link (src, &sb)) != NULL) {
else if ((lp = check_link (src->full_path, &sb)) != NULL) {
err = copy_hardlink (dst, reset_selinux, lp);
}
@@ -449,9 +504,9 @@ static int copy_entry (const char *src, const char *dst,
*
* Return 0 on success, -1 on error.
*/
static int copy_dir (const char *src, const char *dst,
static int copy_dir (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
@@ -463,15 +518,15 @@ static int copy_dir (const char *src, const char *dst,
*/
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst, S_IFDIR) != 0) {
if (set_selinux_file_context (dst->full_path, S_IFDIR) != 0) {
return -1;
}
#endif /* WITH_SELINUX */
if ( (mkdir (dst, statp->st_mode) != 0)
|| (chown_if_needed (dst, statp,
if ( (mkdirat (dst->dirfd, dst->name, statp->st_mode) != 0)
|| (chownat_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_file (src, dst, &ctx) != 0)
|| ( (perm_copy_path (src, dst, &ctx) != 0)
&& (errno != 0))
#else /* !WITH_ACL */
|| (chmod (dst, statp->st_mode) != 0)
@@ -485,19 +540,18 @@ static int copy_dir (const char *src, const char *dst,
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_file (src, dst, NULL, &ctx) != 0)
&& (attr_copy_path (src, dst, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
|| (copy_tree (src, dst, false, reset_selinux,
|| (copy_tree_impl (src, dst, false, reset_selinux,
old_uid, new_uid, old_gid, new_gid) != 0)
|| (utimes (dst, mt) != 0)) {
|| (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) {
err = -1;
}
return err;
}
#ifdef S_IFLNK
/*
* readlink_malloc - wrapper for readlink
*
@@ -544,9 +598,9 @@ static /*@null@*/char *readlink_malloc (const char *filename)
*
* Return 0 on success, -1 on error.
*/
static int copy_symlink (const char *src, const char *dst,
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
unused bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
@@ -564,7 +618,7 @@ static int copy_symlink (const char *src, const char *dst,
* destination directory name.
*/
oldlink = readlink_malloc (src);
oldlink = readlink_malloc (src->full_path);
if (NULL == oldlink) {
return -1;
}
@@ -584,13 +638,13 @@ static int copy_symlink (const char *src, const char *dst,
}
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst, S_IFLNK) != 0) {
if (set_selinux_file_context (dst->full_path, S_IFLNK) != 0) {
free (oldlink);
return -1;
}
#endif /* WITH_SELINUX */
if ( (symlink (oldlink, dst) != 0)
|| (lchown_if_needed (dst, statp,
if ( (symlinkat (oldlink, dst->dirfd, dst->name) != 0)
|| (chownat_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)) {
/* FIXME: there are no modes on symlinks, right?
* ACL could be copied, but this would be much more
@@ -604,18 +658,12 @@ static int copy_symlink (const char *src, const char *dst,
}
free (oldlink);
#ifdef HAVE_LUTIMES
/* 2007-10-18: We don't care about
* exit status of lutimes because
* it returns ENOSYS on many system
* - not implemented
*/
(void) lutimes (dst, mt);
#endif /* HAVE_LUTIMES */
if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) {
return -1;
}
return 0;
}
#endif /* S_IFLNK */
/*
* copy_hardlink - copy a hardlink
@@ -624,13 +672,13 @@ static int copy_symlink (const char *src, const char *dst,
*
* Return 0 on success, -1 on error.
*/
static int copy_hardlink (const char *dst,
static int copy_hardlink (const struct path_info *dst,
unused bool reset_selinux,
struct link_name *lp)
{
/* FIXME: selinux, ACL, Extended Attributes needed? */
if (link (lp->ln_name, dst) != 0) {
if (linkat (AT_FDCWD, lp->ln_name, dst->dirfd, dst->name, 0) != 0) {
return -1;
}
@@ -654,28 +702,28 @@ static int copy_hardlink (const char *dst,
*
* Return 0 on success, -1 on error.
*/
static int copy_special (const char *src, const char *dst,
static int copy_special (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
int err = 0;
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst, statp->st_mode & S_IFMT) != 0) {
if (set_selinux_file_context (dst->full_path, statp->st_mode & S_IFMT) != 0) {
return -1;
}
#endif /* WITH_SELINUX */
if ( (mknod (dst, statp->st_mode & ~07777, statp->st_rdev) != 0)
|| (chown_if_needed (dst, statp,
if ( (mknodat (dst->dirfd, dst->name, statp->st_mode & ~07777U, statp->st_rdev) != 0)
|| (chownat_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_file (src, dst, &ctx) != 0)
|| ( (perm_copy_path (src, dst, &ctx) != 0)
&& (errno != 0))
#else /* !WITH_ACL */
|| (chmod (dst, statp->st_mode & 07777) != 0)
|| (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0)
#endif /* !WITH_ACL */
#ifdef WITH_ATTR
/*
@@ -686,16 +734,52 @@ static int copy_special (const char *src, const char *dst,
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_file (src, dst, NULL, &ctx) != 0)
&& (attr_copy_path (src, dst, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
|| (utimes (dst, mt) != 0)) {
|| (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) {
err = -1;
}
return err;
}
/*
* full_write - write entire buffer
*
* Write up to count bytes from the buffer starting at buf to the
* file referred to by the file descriptor fd.
* Retry in case of a short write.
*
* Returns the number of bytes written on success, -1 on error.
*/
static ssize_t full_write(int fd, const void *buf, size_t count) {
ssize_t written = 0;
while (count > 0) {
ssize_t res;
res = write(fd, buf, count);
if (res < 0) {
if (errno == EINTR) {
continue;
}
return res;
}
if (res == 0) {
break;
}
written += res;
buf = (const unsigned char*)buf + res;
count -= (size_t)res;
}
return written;
}
/*
* copy_file - copy a file
*
@@ -706,34 +790,32 @@ static int copy_special (const char *src, const char *dst,
*
* Return 0 on success, -1 on error.
*/
static int copy_file (const char *src, const char *dst,
static int copy_file (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
int err = 0;
int ifd;
int ofd;
char buf[1024];
ssize_t cnt;
ifd = open (src, O_RDONLY|O_NOFOLLOW);
ifd = openat (src->dirfd, src->name, O_RDONLY|O_NOFOLLOW|O_CLOEXEC);
if (ifd < 0) {
return -1;
}
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst, S_IFREG) != 0) {
if (set_selinux_file_context (dst->full_path, S_IFREG) != 0) {
(void) close (ifd);
return -1;
}
#endif /* WITH_SELINUX */
ofd = open (dst, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, statp->st_mode & 07777);
ofd = openat (dst->dirfd, dst->name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_NOFOLLOW | O_CLOEXEC, statp->st_mode & 07777);
if ( (ofd < 0)
|| (fchown_if_needed (ofd, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_fd (src, ifd, dst, ofd, &ctx) != 0)
|| ( (perm_copy_fd (src->full_path, ifd, dst->full_path, ofd, &ctx) != 0)
&& (errno != 0))
#else /* !WITH_ACL */
|| (fchmod (ofd, statp->st_mode & 07777) != 0)
@@ -747,7 +829,7 @@ static int copy_file (const char *src, const char *dst,
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_fd (src, ifd, dst, ofd, NULL, &ctx) != 0)
&& (attr_copy_fd (src->full_path, ifd, dst->full_path, ofd, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
) {
@@ -758,8 +840,24 @@ static int copy_file (const char *src, const char *dst,
return -1;
}
while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
if (write (ofd, buf, (size_t)cnt) != cnt) {
while (true) {
char buf[8192];
ssize_t cnt;
cnt = read (ifd, buf, sizeof buf);
if (cnt < 0) {
if (errno == EINTR) {
continue;
}
(void) close (ofd);
(void) close (ifd);
return -1;
}
if (cnt == 0) {
break;
}
if (full_write (ofd, buf, (size_t)cnt) < 0) {
(void) close (ofd);
(void) close (ifd);
return -1;
@@ -767,23 +865,13 @@ static int copy_file (const char *src, const char *dst,
}
(void) close (ifd);
#ifdef HAVE_FUTIMES
if (futimes (ofd, mt) != 0) {
(void) close (ofd);
return -1;
}
#endif /* HAVE_FUTIMES */
if (close (ofd) != 0) {
return -1;
}
#ifndef HAVE_FUTIMES
if (utimes(dst, mt) != 0) {
if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) {
return -1;
}
#endif /* !HAVE_FUTIMES */
return err;
}
@@ -818,7 +906,70 @@ static int chown_function ## _if_needed (type_dst dst, \
return chown_function (dst, tmpuid, tmpgid); \
}
def_chown_if_needed (chown, const char *)
def_chown_if_needed (lchown, const char *)
def_chown_if_needed (fchown, int)
static int chownat_if_needed (const struct path_info *dst,
const struct stat *statp,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
uid_t tmpuid = (uid_t) -1;
gid_t tmpgid = (gid_t) -1;
/* Use new_uid if old_uid is set to -1 or if the file was
* owned by the user. */
if (((uid_t) -1 == old_uid) || (statp->st_uid == old_uid)) {
tmpuid = new_uid;
}
/* Otherwise, or if new_uid was set to -1, we keep the same
* owner. */
if ((uid_t) -1 == tmpuid) {
tmpuid = statp->st_uid;
}
if (((gid_t) -1 == old_gid) || (statp->st_gid == old_gid)) {
tmpgid = new_gid;
}
if ((gid_t) -1 == tmpgid) {
tmpgid = statp->st_gid;
}
return fchownat (dst->dirfd, dst->name, tmpuid, tmpgid, AT_SYMLINK_NOFOLLOW);
}
/*
* copy_tree - copy files in a directory tree
*
* 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
* new_uid is set to -1, no ownership will be changed.
*
* The same logic applies for the group-ownership and
* old_gid/new_gid.
*/
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)
{
const struct path_info src = {
.full_path = src_root,
.dirfd = AT_FDCWD,
.name = src_root
};
const struct path_info dst = {
.full_path = dst_root,
.dirfd = AT_FDCWD,
.name = dst_root
};
return copy_tree_impl(&src, &dst, copy_root, reset_selinux,
old_uid, new_uid, old_gid, new_gid);
}
+4 -4
View File
@@ -28,7 +28,7 @@ size_t newenvc = 0;
/*@null@*/char **newenvp = NULL;
extern char **environ;
static const char *forbid[] = {
static const char *const forbid[] = {
"_RLD_=",
"BASH_ENV=", /* GNU creeping featurism strikes again... */
"ENV=",
@@ -47,7 +47,7 @@ static const char *forbid[] = {
/* these are allowed, but with no slashes inside
(to work around security problems in GNU gettext) */
static const char *noslash[] = {
static const char *const noslash[] = {
"LANG=",
"LANGUAGE=",
"LC_", /* anything with the LC_ prefix */
@@ -185,7 +185,7 @@ void set_env (int argc, char *const *argv)
noname++;
addenv (variable, *argv);
} else {
const char **p;
const char *const *p;
for (p = forbid; NULL != *p; p++) {
if (strncmp (*argv, *p, strlen (*p)) == 0) {
@@ -218,7 +218,7 @@ void set_env (int argc, char *const *argv)
void sanitize_env (void)
{
char **envp = environ;
const char **bad;
const char *const *bad;
char **cur;
char **move;
+1 -1
View File
@@ -98,7 +98,7 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
static int check_gid (const gid_t gid,
const gid_t gid_min,
const gid_t gid_max,
bool *used_gids)
const bool *used_gids)
{
/* First test that the preferred ID is in the range */
if (gid < gid_min || gid > gid_max) {
+1 -1
View File
@@ -98,7 +98,7 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
static int check_uid(const uid_t uid,
const uid_t uid_min,
const uid_t uid_max,
bool *used_uids)
const bool *used_uids)
{
/* First test that the preferred ID is in the range */
if (uid < uid_min || uid > uid_max) {
+393 -619
View File
File diff suppressed because it is too large Load Diff
+9 -32
View File
@@ -31,32 +31,9 @@
#include <ctype.h>
#include <time.h>
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
# define IN_CTYPE_DOMAIN(c) 1
#else
# define IN_CTYPE_DOMAIN(c) isascii(c)
#endif
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
- Its arg may be any int or unsigned int; it need not be an unsigned char.
- It's guaranteed to evaluate its argument exactly once.
- It's typically faster.
Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless
it's important to use the locale's definition of `digit' even when the
host does not conform to Posix. */
#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
#include "getdate.h"
#if defined (STDC_HEADERS)
# include <string.h>
#endif
#include <string.h>
/* Some old versions of bison generate parsers that use bcopy.
That loses on systems that don't provide the function, so we have
@@ -651,7 +628,7 @@ static int LookupWord (char *buff)
/* Make it lowercase. */
for (p = buff; '\0' != *p; p++)
if (ISUPPER (*p))
if (isupper (*p))
*p = tolower (*p);
if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
@@ -732,7 +709,7 @@ static int LookupWord (char *buff)
}
/* Military timezones. */
if (buff[1] == '\0' && ISALPHA (*buff))
if (buff[1] == '\0' && isalpha (*buff))
{
for (tp = MilitaryTable; tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
@@ -771,30 +748,30 @@ yylex (void)
for (;;)
{
while (ISSPACE (*yyInput))
while (isspace (*yyInput))
yyInput++;
if (ISDIGIT (c = *yyInput) || c == '-' || c == '+')
if (isdigit (c = *yyInput) || c == '-' || c == '+')
{
if (c == '-' || c == '+')
{
sign = c == '-' ? -1 : 1;
if (!ISDIGIT (*++yyInput))
if (!isdigit (*++yyInput))
/* skip the '-' sign */
continue;
}
else
sign = 0;
for (yylval.Number = 0; ISDIGIT (c = *yyInput++);)
for (yylval.Number = 0; isdigit (c = *yyInput++);)
yylval.Number = 10 * yylval.Number + c - '0';
yyInput--;
if (sign < 0)
yylval.Number = -yylval.Number;
return (0 != sign) ? tSNUMBER : tUNUMBER;
}
if (ISALPHA (c))
if (isalpha (c))
{
for (p = buff; (c = *yyInput++, ISALPHA (c)) || c == '.';)
for (p = buff; (c = *yyInput++, isalpha (c)) || c == '.';)
if (p < &buff[sizeof buff - 1])
*p++ = c;
*p = '\0';
+1 -1
View File
@@ -25,7 +25,7 @@
* If the range is valid, getrange returns 1.
* If the range is not valid, getrange returns 0.
*/
int getrange (char *range,
int getrange (const char *range,
unsigned long *min, bool *has_min,
unsigned long *max, bool *has_max)
{
+4 -4
View File
@@ -102,10 +102,10 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv)
#define ULONG_DIGITS ((((sizeof(unsigned long) * CHAR_BIT) + 9)/10)*3)
#if HAVE_SYS_CAPABILITY_H
static inline bool maps_lower_root(int cap, int ranges, struct map_range *mappings)
static inline bool maps_lower_root(int cap, int ranges, const struct map_range *mappings)
{
int idx;
struct map_range *mapping;
const struct map_range *mapping;
if (cap != CAP_SETUID)
return false;
@@ -135,11 +135,11 @@ static inline bool maps_lower_root(int cap, int ranges, struct map_range *mappin
* when the root user calls the new{g,u}idmap binary for an unprivileged user.
* If this is wanted: use file capabilities!
*/
void write_mapping(int proc_dir_fd, int ranges, struct map_range *mappings,
void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings,
const char *map_file, uid_t ruid)
{
int idx;
struct map_range *mapping;
const struct map_range *mapping;
size_t bufsize;
char *buf, *pos;
int fd;
+3 -3
View File
@@ -7,6 +7,8 @@
#ifndef _IDMAPPING_H_
#define _IDMAPPING_H_
#include <sys/types.h>
struct map_range {
unsigned long upper; /* first ID inside the namespace */
unsigned long lower; /* first ID outside the namespace */
@@ -15,9 +17,7 @@ struct map_range {
extern struct map_range *get_map_ranges(int ranges, int argc, char **argv);
extern void write_mapping(int proc_dir_fd, int ranges,
struct map_range *mappings, const char *map_file, uid_t ruid);
extern void nss_init(char *nsswitch_path);
const struct map_range *mappings, const char *map_file, uid_t ruid);
#endif /* _ID_MAPPING_H_ */
+2 -2
View File
@@ -41,9 +41,9 @@ void login_prompt (const char *prompt, char *name, int namesize)
int i;
FILE *fp;
RETSIGTYPE (*sigquit) (int);
sighandler_t sigquit;
#ifdef SIGTSTP
RETSIGTYPE (*sigtstp) (int);
sighandler_t sigtstp;
#endif
/*
+1 -1
View File
@@ -28,7 +28,7 @@ void motd (void)
char *motdlist;
const char *motdfile;
char *mb;
register int c;
int c;
motdfile = getdef_str ("MOTD_FILE");
if (NULL == motdfile) {
+1 -1
View File
@@ -22,7 +22,7 @@ static int ni_conv (int num_msg,
const struct pam_message **msg,
struct pam_response **resp,
unused void *appdata_ptr);
static struct pam_conv non_interactive_pam_conv = {
static const struct pam_conv non_interactive_pam_conv = {
ni_conv,
NULL
};
+6 -6
View File
@@ -248,7 +248,7 @@ extern struct spwd *prefix_getspnam(const char* name)
}
}
extern void prefix_setpwent()
extern void prefix_setpwent(void)
{
if (!passwd_db_file) {
setpwent();
@@ -261,7 +261,7 @@ extern void prefix_setpwent()
if (!fp_pwent)
return;
}
extern struct passwd* prefix_getpwent()
extern struct passwd* prefix_getpwent(void)
{
if (!passwd_db_file) {
return getpwent();
@@ -271,7 +271,7 @@ extern struct passwd* prefix_getpwent()
}
return fgetpwent(fp_pwent);
}
extern void prefix_endpwent()
extern void prefix_endpwent(void)
{
if (!passwd_db_file) {
endpwent();
@@ -282,7 +282,7 @@ extern void prefix_endpwent()
fp_pwent = NULL;
}
extern void prefix_setgrent()
extern void prefix_setgrent(void)
{
if (!group_db_file) {
setgrent();
@@ -295,14 +295,14 @@ extern void prefix_setgrent()
if (!fp_grent)
return;
}
extern struct group* prefix_getgrent()
extern struct group* prefix_getgrent(void)
{
if (!group_db_file) {
return getgrent();
}
return fgetgrent(fp_grent);
}
extern void prefix_endgrent()
extern void prefix_endgrent(void)
{
if (!group_db_file) {
endgrent();
+68 -77
View File
@@ -11,6 +11,7 @@
#ident "$Id$"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -21,6 +22,72 @@
#include "prototypes.h"
#include "defines.h"
static int remove_tree_at (int at_fd, const char *path, bool remove_root)
{
DIR *dir;
const struct dirent *ent;
int dir_fd, rc = 0;
dir_fd = openat (at_fd, path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
if (dir_fd < 0) {
return -1;
}
dir = fdopendir (dir_fd);
if (!dir) {
(void) close (dir_fd);
return -1;
}
/*
* Open the source directory and delete each entry.
*/
while ((ent = readdir (dir))) {
struct stat ent_sb;
/*
* Skip the "." and ".." entries
*/
if (strcmp (ent->d_name, ".") == 0 ||
strcmp (ent->d_name, "..") == 0) {
continue;
}
rc = fstatat (dirfd(dir), ent->d_name, &ent_sb, AT_SYMLINK_NOFOLLOW);
if (rc < 0) {
break;
}
if (S_ISDIR (ent_sb.st_mode)) {
/*
* Recursively delete this directory.
*/
if (remove_tree_at (dirfd(dir), ent->d_name, true) != 0) {
rc = -1;
break;
}
} else {
/*
* Delete the file.
*/
if (unlinkat (dirfd(dir), ent->d_name, 0) != 0) {
rc = -1;
break;
}
}
}
(void) closedir (dir);
if (remove_root && (0 == rc)) {
if (unlinkat (at_fd, path, AT_REMOVEDIR) != 0) {
rc = -1;
}
}
return rc;
}
/*
* remove_tree - delete a directory tree
*
@@ -28,83 +95,7 @@
* and directories.
* At the end, it deletes the root directory itself.
*/
int remove_tree (const char *root, bool remove_root)
{
char *new_name = NULL;
int err = 0;
struct DIRECT *ent;
struct stat sb;
DIR *dir;
/*
* Open the source directory and read each entry. Every file
* entry in the directory is copied with the UID and GID set
* to the provided values. As an added security feature only
* regular files (and directories ...) are copied, and no file
* is made set-ID.
*/
dir = opendir (root);
if (NULL == dir) {
return -1;
}
while ((ent = readdir (dir))) {
size_t new_len = strlen (root) + strlen (ent->d_name) + 2;
/*
* Skip the "." and ".." entries
*/
if (strcmp (ent->d_name, ".") == 0 ||
strcmp (ent->d_name, "..") == 0) {
continue;
}
/*
* Make the filename for the current entry.
*/
free (new_name);
new_name = (char *) malloc (new_len);
if (NULL == new_name) {
err = -1;
break;
}
(void) snprintf (new_name, new_len, "%s/%s", root, ent->d_name);
if (LSTAT (new_name, &sb) == -1) {
continue;
}
if (S_ISDIR (sb.st_mode)) {
/*
* Recursively delete this directory.
*/
if (remove_tree (new_name, true) != 0) {
err = -1;
break;
}
} else {
/*
* Delete the file.
*/
if (unlink (new_name) != 0) {
err = -1;
break;
}
}
}
if (NULL != new_name) {
free (new_name);
}
(void) closedir (dir);
if (remove_root && (0 == err)) {
if (rmdir (root) != 0) {
err = -1;
}
}
return err;
return remove_tree_at (AT_FDCWD, root, remove_root);
}
+1 -1
View File
@@ -79,7 +79,7 @@ static void change_root (const char* newroot)
if ('/' != newroot[0]) {
fprintf (log_get_logfd(),
_("%s: invalid chroot path '%s'\n"),
_("%s: invalid chroot path '%s', only absolute paths are supported.\n"),
log_get_progname(), newroot);
exit (E_BAD_ARG);
}
+22 -20
View File
@@ -99,15 +99,15 @@ static /*@observer@*/const char *gensalt (size_t salt_size);
static long shadow_random (long min, long max);
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
#ifdef USE_SHA_CRYPT
static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds);
static /*@observer@*/unsigned long SHA_get_salt_rounds (/*@null@*/const int *prefered_rounds);
static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds);
#endif /* USE_SHA_CRYPT */
#ifdef USE_BCRYPT
static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds);
static /*@observer@*/unsigned long BCRYPT_get_salt_rounds (/*@null@*/const int *prefered_rounds);
static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds);
#endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
static /*@observer@*/const unsigned long YESCRYPT_get_salt_cost (/*@null@*/int *prefered_cost);
static /*@observer@*/unsigned long YESCRYPT_get_salt_cost (/*@null@*/const int *prefered_cost);
static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost);
#endif /* USE_YESCRYPT */
@@ -156,26 +156,28 @@ static long read_random_bytes (void)
/* arc4random_buf, if it exists, can never fail. */
arc4random_buf (&randval, sizeof (randval));
goto end;
#endif
#elif defined(HAVE_GETENTROPY)
#ifdef HAVE_GETENTROPY
/* getentropy may exist but lack kernel support. */
if (getentropy (&randval, sizeof (randval))) {
goto fail;
if (getentropy (&randval, sizeof (randval)) == 0) {
goto end;
}
#endif
goto end;
#elif defined(HAVE_GETRANDOM)
#ifdef HAVE_GETRANDOM
/* Likewise getrandom. */
if ((size_t) getrandom (&randval, sizeof (randval), 0) != sizeof (randval)) {
if ((size_t) getrandom (&randval, sizeof (randval), 0) == sizeof (randval)) {
goto end;
}
#endif
/* Use /dev/urandom as a last resort. */
FILE *f = fopen ("/dev/urandom", "r");
if (NULL == f) {
goto fail;
}
goto end;
#else
FILE *f = fopen ("/dev/urandom", "r");
if (fread (&randval, sizeof (randval), 1, f) != 1) {
fclose(f);
goto fail;
@@ -183,7 +185,6 @@ static long read_random_bytes (void)
fclose(f);
goto end;
#endif
fail:
fprintf (log_get_logfd(),
@@ -220,7 +221,7 @@ static long shadow_random (long min, long max)
#ifdef USE_SHA_CRYPT
/* Return the the rounds number for the SHA crypt methods. */
static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds)
static /*@observer@*/unsigned long SHA_get_salt_rounds (/*@null@*/const int *prefered_rounds)
{
unsigned long rounds;
@@ -294,7 +295,7 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long round
#ifdef USE_BCRYPT
/* Return the the rounds number for the BCRYPT method. */
static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds)
static /*@observer@*/unsigned long BCRYPT_get_salt_rounds (/*@null@*/const int *prefered_rounds)
{
unsigned long rounds;
@@ -338,9 +339,10 @@ static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *
/*
* Use 19 as an upper bound for now,
* because musl doesn't allow rounds >= 20.
* If musl ever supports > 20 rounds,
* rounds should be set to B_ROUNDS_MAX.
*/
if (rounds > 19) {
/* rounds = B_ROUNDS_MAX; */
rounds = 19;
}
#endif /* USE_XCRYPT_GENSALT */
@@ -372,7 +374,7 @@ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long ro
#ifdef USE_YESCRYPT
/* Return the the cost number for the YESCRYPT method. */
static /*@observer@*/const unsigned long YESCRYPT_get_salt_cost (/*@null@*/int *prefered_cost)
static /*@observer@*/unsigned long YESCRYPT_get_salt_cost (/*@null@*/const int *prefered_cost)
{
unsigned long cost;
+1 -1
View File
@@ -45,7 +45,7 @@ int shell (const char *file, /*@null@*/const char *arg, char *const envp[])
* don't want to tell us what it is themselves.
*/
if (arg == (char *) 0) {
(void) snprintf (arg0, sizeof arg0, "-%s", Basename ((char *) file));
(void) snprintf (arg0, sizeof arg0, "-%s", Basename (file));
arg0[sizeof arg0 - 1] = '\0';
arg = arg0;
}
+4 -4
View File
@@ -96,7 +96,7 @@ long strtoday (const char *str)
* for now we allow just one format, but we can define more later
* (we try them all until one succeeds). --marekm
*/
static char *date_formats[] = {
static const char *const date_formats[] = {
"%Y-%m-%d",
(char *) 0
};
@@ -106,12 +106,12 @@ static char *date_formats[] = {
* current month, and the cumulative number of days in the preceding
* months. they are declared so that january is 1, not 0.
*/
static short days[13] = { 0,
static const short days[13] = { 0,
31, 28, 31, 30, 31, 30, /* JAN - JUN */
31, 31, 30, 31, 30, 31
}; /* JUL - DEC */
static short juldays[13] = { 0,
static const short juldays[13] = { 0,
0, 31, 59, 90, 120, 151, /* JAN - JUN */
181, 212, 243, 273, 304, 334
}; /* JUL - DEC */
@@ -129,7 +129,7 @@ long strtoday (const char *str)
{
#ifdef HAVE_STRPTIME
struct tm tp;
char *const *fmt;
const char *const *fmt;
char *cp;
time_t result;
+1 -2
View File
@@ -66,7 +66,6 @@
"x" STRINGIZE(FUNCTION_NAME));
exit (13);
}
errno = 0;
status = REENTRANT_NAME(ARG_NAME, result, buffer,
length, &resbuf);
if ((0 == status) && (resbuf == result)) {
@@ -78,7 +77,7 @@
return ret_result;
}
if (ERANGE != errno) {
if (ERANGE != status) {
free (buffer);
free (result);
return NULL;
+3 -3
View File
@@ -26,11 +26,11 @@
#include "prototypes.h"
#include "shadowlog.h"
/*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/char *xmalloc (size_t size)
/*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size)
{
char *ptr;
void *ptr;
ptr = (char *) malloc (size);
ptr = malloc (size);
if (NULL == ptr) {
(void) fprintf (log_get_logfd(),
_("%s: failed to allocate memory: %s\n"),