diff -cpbrN fileutils-4.0/aclocal.m4 fileutils/aclocal.m4 *** fileutils-4.0/aclocal.m4 Sat Nov 14 13:24:53 1998 --- fileutils/aclocal.m4 Thu May 4 10:39:52 2000 *************** dnl Usage: *** 41,47 **** dnl AM_INIT_AUTOMAKE(package,version, [no-define]) AC_DEFUN(AM_INIT_AUTOMAKE, ! [AC_REQUIRE([AM_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) VERSION=[$2] --- 41,47 ---- dnl AM_INIT_AUTOMAKE(package,version, [no-define]) AC_DEFUN(AM_INIT_AUTOMAKE, ! [AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) VERSION=[$2] diff -cpbrN fileutils-4.0/src/Makefile.am fileutils/src/Makefile.am *** fileutils-4.0/src/Makefile.am Sat May 30 20:09:28 1998 --- fileutils/src/Makefile.am Thu May 4 10:55:34 2000 *************** EXTRA_DIST = dcgen dircolors.hin automak *** 22,28 **** INCLUDES = -I.. -I$(srcdir) -I$(top_srcdir)/lib -I../intl DEFS = -DLOCALEDIR=\"$(localedir)\" -DSHAREDIR=\"$(datadir)\" @DEFS@ ! LDADD = @INTLLIBS@ ../lib/libfu.a $(bin_PROGRAMS) $(libexec_PROGRAMS): ../lib/libfu.a --- 22,28 ---- INCLUDES = -I.. -I$(srcdir) -I$(top_srcdir)/lib -I../intl DEFS = -DLOCALEDIR=\"$(localedir)\" -DSHAREDIR=\"$(datadir)\" @DEFS@ ! LDADD = @INTLLIBS@ ../lib/libfu.a -lvsd $(bin_PROGRAMS) $(libexec_PROGRAMS): ../lib/libfu.a diff -cpbrN fileutils-4.0/src/chgrp.c fileutils/src/chgrp.c *** fileutils-4.0/src/chgrp.c Sat Sep 19 18:09:23 1998 --- fileutils/src/chgrp.c Thu May 4 10:48:24 2000 *************** *** 30,35 **** --- 30,37 ---- #include "savedir.h" #include "group-member.h" + #include + /* MAXUID may come from limits.h *or* sys/params.h (via system.h) above. */ #ifndef MAXUID # define MAXUID INT_MAX *************** static int change_dir_group PARAMS ((con *** 74,79 **** --- 76,84 ---- /* The name the program was run with. */ char *program_name; + /* If nonzero, calling user is the 'admin' user. */ + static int virtual_server_admin; + /* If nonzero, and the systems has support for it, change the ownership of symbolic links rather than any files they point to. */ static int change_symlinks; *************** change_file_group (const char *file, int *** 189,194 **** --- 194,213 ---- return 1; } + if (vsd_admin_user (getuid ())) + { + /* Called by the user `admin'. Files can only be altered if the + file's uid and gid are within the uid and gid ranges allocated + to the virtual server. */ + if (vsd_valid_uid (file_stats.st_uid) != 1 + || vsd_valid_gid (file_stats.st_gid) != 1 + || vsd_valid_gid (group) != 1) + { + error (0, errno, "%s", file); + return 1; + } + } + if (group != file_stats.st_gid) { int fail; *************** main (int argc, char **argv) *** 331,336 **** --- 350,370 ---- setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("chgrp: access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + { + seteuid (getuid ()); + virtual_server_admin = 0; + } + else + virtual_server_admin = 1; recurse = force_silent = 0; diff -cpbrN fileutils-4.0/src/chmod.c fileutils/src/chmod.c *** fileutils-4.0/src/chmod.c Sat Sep 19 18:09:23 1998 --- fileutils/src/chmod.c Thu May 4 10:48:45 2000 *************** *** 29,34 **** --- 29,36 ---- #include "savedir.h" #include "filemode.h" + #include + enum Change_status { CH_SUCCEEDED, *************** static int change_dir_mode PARAMS ((cons *** 57,62 **** --- 59,67 ---- /* The name the program was run with. */ char *program_name; + /* If nonzero, calling user is the 'admin' user. */ + static int virtual_server_admin; + /* If nonzero, change the modes of directories recursively. */ static int recurse; *************** change_file_mode (const char *file, cons *** 137,142 **** --- 142,148 ---- error (0, errno, "%s", file); return 1; } + #ifdef S_ISLNK if (S_ISLNK (file_stats.st_mode)) { *************** change_file_mode (const char *file, cons *** 152,157 **** --- 158,176 ---- } #endif + if (virtual_server_admin) + { + /* Called by the user `admin'. Files can only be altered if the + file's uid and gid are within the uid and gid ranges allocated + to the virtual server. */ + if (vsd_valid_uid (file_stats.st_uid) != 1 + || vsd_valid_gid (file_stats.st_gid) != 1) + { + error (0, errno, "%s", file); + return 1; + } + } + newmode = mode_adjust (file_stats.st_mode, changes); if (newmode != (file_stats.st_mode & 07777)) *************** main (int argc, char **argv) *** 278,283 **** --- 297,317 ---- setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("chmod: access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + { + seteuid (getuid ()); + virtual_server_admin = 0; + } + else + virtual_server_admin = 1; recurse = force_silent = 0; diff -cpbrN fileutils-4.0/src/chown.c fileutils/src/chown.c *** fileutils-4.0/src/chown.c Sat Sep 19 18:09:23 1998 --- fileutils/src/chown.c Thu May 4 10:49:11 2000 *************** *** 41,46 **** --- 41,48 ---- #include "savedir.h" #include "lchown.h" + #include + #ifndef _POSIX_VERSION struct passwd *getpwnam (); struct group *getgrnam (); *************** static int change_dir_owner PARAMS ((con *** 80,85 **** --- 82,90 ---- /* The name the program was run with. */ char *program_name; + /* If nonzero, calling user is the 'admin' user. */ + static int virtual_server_admin; + /* If nonzero, and the systems has support for it, change the ownership of symbolic links rather than any files they point to. */ static int change_symlinks = 1; *************** change_file_owner (int cmdline_arg, cons *** 179,186 **** --- 184,206 ---- return 1; } + if (virtual_server_admin) + { + /* Called by the user `admin'. File can only be set to a uid + with the uid and gid ranges allocated to the virtual server. */ + if (vsd_valid_uid (file_stats.st_uid) != 1 + || vsd_valid_gid (file_stats.st_gid) != 1 + || (user != -1 && vsd_valid_uid (user) != 1) + || (group != -1 && vsd_valid_gid (group) != 1)) + { + error (0, errno, "%s", file); + return 1; + } + } + newuser = user == (uid_t) -1 ? file_stats.st_uid : user; newgroup = group == (gid_t) -1 ? file_stats.st_gid : group; + if (newuser != file_stats.st_uid || newgroup != file_stats.st_gid) { int fail; *************** main (int argc, char **argv) *** 332,337 **** --- 352,372 ---- setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("chown access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + { + seteuid (getuid ()); + virtual_server_admin = 0; + } + else + virtual_server_admin = 1; recurse = force_silent = 0; diff -cpbrN fileutils-4.0/src/copy.c fileutils/src/copy.c *** fileutils-4.0/src/copy.c Mon Sep 28 17:09:18 1998 --- fileutils/src/copy.c Thu May 4 10:49:43 2000 *************** *** 34,39 **** --- 34,41 ---- #include "cp-hash.h" #include "path-concat.h" + #include + #define DO_CHOWN(Chown, File, New_uid, New_gid) \ (Chown ((File), (x->myeuid == 0 ? (New_uid) : x->myeuid), (New_gid)) \ /* If non-root uses -p, it's ok if we can't preserve ownership. \ *************** copy_reg (const char *src_path, const ch *** 176,181 **** --- 178,196 ---- int last_write_made_hole = 0; int make_holes = (sparse_mode == SPARSE_ALWAYS); + /* We must have read access to src_path. */ + if (vsd_check_path (src_path, 1, R_OK)) + { + error (0, errno, "%s", src_path); + return -1; + } + /* We must have write access to dst_path. */ + if (vsd_check_path (dst_path, 1, W_OK)) + { + error (0, errno, "%s", dst_path); + return -1; + } + source_desc = open (src_path, O_RDONLY); if (source_desc < 0) { *************** copy_reg (const char *src_path, const ch *** 327,333 **** } ret: ! if (close (dest_desc) < 0) { error (0, errno, "%s", dst_path); return_val = -1; --- 342,349 ---- } ret: ! if (close (dest_desc) < 0 ! || chown (dst_path, getuid (), getgid ())) { error (0, errno, "%s", dst_path); return_val = -1; *************** copy_internal (const char *src_path, con *** 493,498 **** --- 509,515 ---- if (!S_ISDIR (src_type) && !x->force && x->interactive) { + /* NAB HERE */ if (euidaccess (dst_path, W_OK) != 0) { fprintf (stderr, *************** copy_internal (const char *src_path, con *** 516,521 **** --- 533,545 ---- return 1; } + /* NAB: check dst_path here */ + if (vsd_check_path (dst_path, 1, W_OK)) + { + error (0, errno, "%s", dst_path); + return -1; + } + if (x->backup_type != none && !S_ISDIR (dst_sb.st_mode)) { char *tmp_backup = find_backup_file_name (dst_path, *************** copy_internal (const char *src_path, con *** 587,592 **** --- 611,629 ---- } } + /* NAB check src_path and dst_path here */ + if (vsd_check_path (src_path, 1, R_OK)) + { + error (0, errno, "%s", src_path); + return -1; + } + + if (vsd_check_path (dst_path, 1, W_OK)) + { + error (0, errno, "%s", dst_path); + return -1; + } + /* If the source is a directory, we don't always create the destination directory. So --verbose should not announce anything until we're sure we'll create a directory. */ *************** copy_internal (const char *src_path, con *** 659,664 **** --- 696,703 ---- goto un_backup; } + chown (dst_path, getuid (), getgid ()); + /* Insert the created directory's inode and device numbers into the search structure, so that we can avoid copying it again. */ *************** copy_internal (const char *src_path, con *** 849,854 **** --- 888,906 ---- if (DO_CHOWN (chown, dst_path, src_sb.st_uid, src_sb.st_gid)) { error (0, errno, _("preserving ownership for %s"), dst_path); + if (x->require_preserve) + return 1; + } + } + else + { + + #if 0 + fprintf (stderr, "dstpath = '%s', euid = %d, egid = %d\n", dst_path, geteuid (), getegid ()); + #endif + if (chown (dst_path, getuid (), getgid ())) + { + error (0, errno, _("fixing ownership for %s"), dst_path); if (x->require_preserve) return 1; } diff -cpbrN fileutils-4.0/src/cp.c fileutils/src/cp.c *** fileutils-4.0/src/cp.c Sat Sep 19 18:09:23 1998 --- fileutils/src/cp.c Thu May 4 10:50:01 2000 *************** *** 36,41 **** --- 36,43 ---- #include "copy.h" #include "error.h" + #include + #ifndef _POSIX_VERSION uid_t geteuid (); #endif *************** make_path_private (const char *const_dir *** 342,347 **** --- 344,356 ---- for example, in the command `cp --parents ../a/../b/c e_dir', make_path_private creates only e_dir/../a if ./b already exists. */ + + if (vsd_check_path (dirpath, 1, W_OK)) + { + error (0, errno, "%s", dirpath); + return -1; + } + *new_dst = 1; new->is_new_dir = 1; if (mkdir (dirpath, mode)) *************** make_path_private (const char *const_dir *** 351,356 **** --- 360,366 ---- } else { + chown (dirpath, getuid (), getgid ()); if (verbose_fmt_string != NULL) printf (verbose_fmt_string, src, dirpath); } *************** main (int argc, char **argv) *** 638,643 **** --- 648,663 ---- setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("cp: access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + seteuid (getuid ()); cp_option_init (&x); diff -cpbrN fileutils-4.0/src/ls.c fileutils/src/ls.c *** fileutils-4.0/src/ls.c Thu May 4 10:26:18 2000 --- fileutils/src/ls.c Thu May 4 10:50:31 2000 *************** *** 74,79 **** --- 74,81 ---- #include "quotearg.h" #include "filemode.h" + #include + #define obstack_chunk_alloc malloc #define obstack_chunk_free free *************** main (int argc, char **argv) *** 681,686 **** --- 683,699 ---- register struct pending *thispend; program_name = argv[0]; + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("ls: access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + seteuid (getuid ()); + setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); diff -cpbrN fileutils-4.0/src/mkdir.c fileutils/src/mkdir.c *** fileutils-4.0/src/mkdir.c Sat Sep 19 18:09:23 1998 --- fileutils/src/mkdir.c Thu May 4 10:50:46 2000 *************** *** 28,33 **** --- 28,35 ---- #include "closeout.h" #include "error.h" + #include + /* The name this program was run with. */ char *program_name; *************** main (int argc, char **argv) *** 85,90 **** --- 87,103 ---- int optc; program_name = argv[0]; + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("mkdir: access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + seteuid (getuid ()); + setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); *************** main (int argc, char **argv) *** 146,159 **** errors |= make_path (argv[optind], newmode, parent_mode, -1, -1, 1, verbose_fmt_string); } ! else if (mkdir (argv[optind], newmode)) { ! error (0, errno, _("cannot make directory `%s'"), argv[optind]); errors = 1; } ! else if (verbose_fmt_string) { error (0, 0, verbose_fmt_string, argv[optind]); } } --- 159,186 ---- errors |= make_path (argv[optind], newmode, parent_mode, -1, -1, 1, verbose_fmt_string); } ! else ! { ! if (vsd_check_path (argv[optind], 0, R_OK | W_OK)) ! { ! error (0, errno, "%s", argv[optind]); ! errors = 1; ! } ! else { ! if (mkdir (argv[optind], newmode)) ! { ! error (0, errno, _("cannot create directory `%s'"), ! argv[optind]); errors = 1; } ! else { + chown (argv[optind], getuid (), getgid ()); + if (verbose_fmt_string) error (0, 0, verbose_fmt_string, argv[optind]); + } + } } } diff -cpbrN fileutils-4.0/src/mv.c fileutils/src/mv.c *** fileutils-4.0/src/mv.c Thu May 4 10:26:28 2000 --- fileutils/src/mv.c Thu May 4 10:51:05 2000 *************** *** 56,61 **** --- 56,63 ---- #include "remove.h" #include "error.h" + #include + /* Initial number of entries in each hash table entry's table of inodes. */ #define INITIAL_HASH_MODULE 100 *************** main (int argc, char **argv) *** 395,400 **** --- 397,412 ---- setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("mv: access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + seteuid (getuid ()); cp_option_init (&x); diff -cpbrN fileutils-4.0/src/remove.c fileutils/src/remove.c *** fileutils-4.0/src/remove.c Wed Nov 4 02:58:20 1998 --- fileutils/src/remove.c Thu May 4 10:51:25 2000 *************** typedef enum {false = 0, true = 1} bool; *** 40,45 **** --- 40,47 ---- #include "hash.h" #include "remove.h" + #include + #define obstack_chunk_alloc malloc #define obstack_chunk_free free *************** remove_file (struct File_spec *fs, const *** 613,618 **** --- 615,629 ---- int asked = 0; char *pathname = fs->filename; + /* Stop a user deleting files that do not belong to their virtual + server. */ + if (vsd_check_path (pathname, 1, R_OK | W_OK)) + { + /* User does not have write access to the directory or the file. */ + error (0, errno, "%s: permission denied", full_filename (pathname)); + return RM_ERROR; + } + if (!x->ignore_missing_files && (x->interactive || x->stdin_tty) && euidaccess (pathname, W_OK)) { *************** remove_dir (struct File_spec *fs, int ne *** 672,677 **** --- 683,698 ---- if (!x->recursive) { error (0, 0, _("%s: is a directory"), full_filename (dir_name)); + return RM_ERROR; + } + + /* Stop a user deleting files that do not belong to their virtual + server. */ + if (vsd_check_path (dir_name, 1, R_OK | W_OK)) + { + /* User does not have write access to the directory or write + access to the file. */ + error (0, errno, "%s", full_filename (dir_name)); return RM_ERROR; } diff -cpbrN fileutils-4.0/src/rm.c fileutils/src/rm.c *** fileutils-4.0/src/rm.c Sat Sep 19 18:09:23 1998 --- fileutils/src/rm.c Thu May 4 10:51:38 2000 *************** *** 55,60 **** --- 55,62 ---- #include "error.h" #include "remove.h" + #include + void strip_trailing_slashes (); /* Name this program was run with. */ *************** main (int argc, char **argv) *** 126,131 **** --- 128,143 ---- setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("rm: access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + seteuid (getuid ()); rm_option_init (&x); diff -cpbrN fileutils-4.0/src/rmdir.c fileutils/src/rmdir.c *** fileutils-4.0/src/rmdir.c Sat Sep 19 18:09:23 1998 --- fileutils/src/rmdir.c Thu May 4 10:51:48 2000 *************** *** 31,36 **** --- 31,38 ---- #include "closeout.h" #include "error.h" + #include + #ifndef EEXIST # define EEXIST 0 #endif *************** main (int argc, char **argv) *** 148,153 **** --- 150,166 ---- int optc; program_name = argv[0]; + + if (vsd_validate_user_uid (getuid ()) != 1) + { + printf ("rmdir: access denied: %s\n", strerror (errno)); + return 1; + } + + /* Drop setuid priviledges if not the admin user. */ + if (vsd_admin_user (getuid ()) != 1) + seteuid (getuid ()); + setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); *************** main (int argc, char **argv) *** 198,209 **** /* Stripping slashes is harmless for rmdir; if the arg is not a directory, it will fail with ENOTDIR. */ strip_trailing_slashes (dir); /* Give a diagnostic for each attempted removal if --verbose. */ if (verbose) error (0, errno, _("removing directory, %s"), dir); - - fail = rmdir (dir); if (fail) { --- 211,221 ---- /* Stripping slashes is harmless for rmdir; if the arg is not a directory, it will fail with ENOTDIR. */ strip_trailing_slashes (dir); + fail = vsd_check_path (dir, 1, R_OK | W_OK) ? 1 : rmdir (dir); /* Give a diagnostic for each attempted removal if --verbose. */ if (verbose) error (0, errno, _("removing directory, %s"), dir); if (fail) {