diff -u -r fileutils-4.1.orig/lib/makepath.c fileutils-4.1/lib/makepath.c --- fileutils-4.1.orig/lib/makepath.c Sun Nov 5 13:10:25 2000 +++ fileutils-4.1/lib/makepath.c Tue Jun 25 11:11:19 2002 @@ -117,6 +117,7 @@ #include "save-cwd.h" #include "error.h" #include "quote.h" +#include void strip_trailing_slashes (); @@ -188,6 +189,16 @@ /* DIR (aka DIRPATH) already exists and is a directory. */ } } + else + { + /* VSD added chown, so that a recursive create will end up + with the correct ownership */ + fail = chown (dir, getuid (), getgid ()); + if (fail) + error (0, errno, _("cannot set ownership of directory %s"), + quote (dir)); + } + if (created_dir_p) *created_dir_p = created_dir; diff -u -r fileutils-4.1.orig/src/Makefile.am fileutils-4.1/src/Makefile.am --- fileutils-4.1.orig/src/Makefile.am Tue Jun 25 11:57:59 2002 +++ fileutils-4.1/src/Makefile.am Tue Jun 25 11:11:19 2002 @@ -17,7 +17,7 @@ INCLUDES = -I.. -I$(srcdir) -I$(top_srcdir)/lib -I../intl DEFS = -DLOCALEDIR=\"$(localedir)\" -DSHAREDIR=\"$(datadir)\" @DEFS@ -LDADD = @INTLLIBS@ ../lib/libfetish.a +LDADD = @INTLLIBS@ ../lib/libfetish.a -lvsd dir_LDADD = $(LDADD) ls_LDADD = $(LDADD) diff -u -r fileutils-4.1.orig/src/Makefile.in fileutils-4.1/src/Makefile.in --- fileutils-4.1.orig/src/Makefile.in Tue Jun 25 11:57:59 2002 +++ fileutils-4.1/src/Makefile.in Tue Jun 25 11:11:19 2002 @@ -137,7 +137,7 @@ INCLUDES = -I.. -I$(srcdir) -I$(top_srcdir)/lib -I../intl DEFS = -DLOCALEDIR=\"$(localedir)\" -DSHAREDIR=\"$(datadir)\" @DEFS@ -LDADD = @INTLLIBS@ ../lib/libfetish.a +LDADD = @INTLLIBS@ ../lib/libfetish.a -lvsd dir_LDADD = $(LDADD) -ltermcap ls_LDADD = $(LDADD) -ltermcap diff -u -r fileutils-4.1.orig/src/chgrp.c fileutils-4.1/src/chgrp.c --- fileutils-4.1.orig/src/chgrp.c Sun Jan 7 09:19:44 2001 +++ fileutils-4.1/src/chgrp.c Tue Jun 25 11:11:19 2002 @@ -37,6 +37,8 @@ #define AUTHORS "David MacKenzie" +#include + /* MAXUID may come from limits.h *or* sys/params.h (via system.h) above. */ #ifndef MAXUID # define MAXUID UID_T_MAX @@ -56,6 +58,9 @@ /* The name the program was run with. */ char *program_name; +/* If nonzero, calling user is the 'admin' user. */ +static int virtual_server_admin; + /* The argument to the --reference option. Use the group ID of this file. This file must exist. */ static char *reference_file; @@ -164,6 +169,21 @@ 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; + atexit (close_stdout); chopt_init (&chopt); diff -u -r fileutils-4.1.orig/src/chmod.c fileutils-4.1/src/chmod.c --- fileutils-4.1.orig/src/chmod.c Sun Nov 19 16:56:33 2000 +++ fileutils-4.1/src/chmod.c Tue Jun 25 11:11:19 2002 @@ -34,6 +34,8 @@ #define AUTHORS "David MacKenzie" +#include + enum Change_status { CH_SUCCEEDED, @@ -62,6 +64,9 @@ /* 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; @@ -171,6 +176,7 @@ error (0, errno, _("getting attributes of %s"), quote (file)); return 1; } + #ifdef S_ISLNK if (S_ISLNK (file_stats.st_mode)) { @@ -186,6 +192,19 @@ } #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); fail = chmod (file, newmode); @@ -306,6 +325,21 @@ 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; + atexit (close_stdout); recurse = force_silent = 0; diff -u -r fileutils-4.1.orig/src/chown-core.c fileutils-4.1/src/chown-core.c --- fileutils-4.1.orig/src/chown-core.c Sat Dec 16 18:51:27 2000 +++ fileutils-4.1/src/chown-core.c Tue Jun 25 11:11:19 2002 @@ -30,6 +30,10 @@ #include "savedir.h" #include "chown-core.h" #include "xalloc.h" +#include + +/* If nonzero, calling user is the 'admin' user. */ +static int virtual_server_admin; /* The number of decimal digits required to represent the largest value of type `unsigned int'. This is enough for an 8-byte unsigned int type. */ @@ -239,6 +243,31 @@ 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; + + /* vsd specific permission checking: */ + 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 + || (uid != -1 && vsd_valid_uid (uid) != 1) + || (gid != -1 && vsd_valid_gid (gid) != 1)) + { + error (0, errno, "%s", file); + return 1; + } + } + /* If it's a symlink and we're dereferencing, then use stat to get the attributes of the referent. */ if (S_ISLNK (file_stats.st_mode)) diff -u -r fileutils-4.1.orig/src/chown.c fileutils-4.1/src/chown.c --- fileutils-4.1.orig/src/chown.c Sat Feb 17 14:12:51 2001 +++ fileutils-4.1/src/chown.c Tue Jun 25 11:11:19 2002 @@ -45,6 +45,8 @@ #define AUTHORS "David MacKenzie" +#include + #ifndef _POSIX_VERSION struct passwd *getpwnam (); struct group *getgrnam (); @@ -61,6 +63,9 @@ /* The name the program was run with. */ char *program_name; +/* If nonzero, calling user is the 'admin' user. */ +static int virtual_server_admin; + /* The argument to the --reference option. Use the owner and group IDs of this file. This file must exist. */ static char *reference_file; @@ -154,6 +159,21 @@ 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; + atexit (close_stdout); chopt_init (&chopt); diff -u -r fileutils-4.1.orig/src/copy.c fileutils-4.1/src/copy.c --- fileutils-4.1.orig/src/copy.c Tue Jun 25 11:57:59 2002 +++ fileutils-4.1/src/copy.c Tue Jun 25 11:57:13 2002 @@ -37,6 +37,8 @@ #include "quote.h" #include "same.h" +#include + #define DO_CHOWN(Chown, File, New_uid, New_gid) \ (Chown (File, New_uid, New_gid) \ /* If non-root uses -p, it's ok if we can't preserve ownership. \ @@ -157,6 +159,9 @@ &local_copy_into_self, NULL); *copy_into_self |= local_copy_into_self; + /* VSD: chown files to user calling copy */ + ret |= chown (dst_path, getuid (), getgid ()); + /* Free the memory for `src_path'. The memory for `dst_path' cannot be deallocated, since it is used to create multiple hard links. */ @@ -194,6 +199,19 @@ int last_write_made_hole = 0; int make_holes = (x->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) { @@ -656,22 +674,21 @@ if (!S_ISDIR (src_type) && x->interactive) { + /* NAB HERE */ if (euidaccess (dst_path, W_OK) != 0) { fprintf (stderr, _("%s: overwrite %s, overriding mode %04lo? "), program_name, quote (dst_path), (unsigned long) (dst_sb.st_mode & CHMOD_MODE_BITS)); - if(!yesno()) - return (move_mode ? 1 : 0); } - else if(x->interactive) + else { fprintf (stderr, _("%s: overwrite %s? "), program_name, quote (dst_path)); - if(!yesno()) - return (move_mode ? 1 : 0); } + if (!yesno ()) + return (move_mode ? 1 : 0); } if (move_mode) @@ -694,6 +711,13 @@ } } + /* 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, @@ -754,6 +778,19 @@ } } + /* 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. */ @@ -901,6 +938,8 @@ 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. */ @@ -1130,6 +1169,11 @@ return 1; } } + else + { + /* VSD: Chown anyway */ + chown (dst_path, getuid (), getgid ()); + } /* Permissions of newly-created regular files were set upon `open' in copy_reg. But don't return early if there were any special bits and diff -u -r fileutils-4.1.orig/src/cp.c fileutils-4.1/src/cp.c --- fileutils-4.1.orig/src/cp.c Sat Feb 3 16:48:34 2001 +++ fileutils-4.1/src/cp.c Tue Jun 25 11:11:19 2002 @@ -52,6 +52,8 @@ #define AUTHORS "Torbjorn Granlund, David MacKenzie, and Jim Meyering" +#include + #ifndef _POSIX_VERSION uid_t geteuid (); #endif @@ -384,6 +386,13 @@ 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)) @@ -394,6 +403,7 @@ } else { + chown (dirpath, getuid (), getgid ()); if (verbose_fmt_string != NULL) printf (verbose_fmt_string, src, dirpath); } @@ -711,6 +721,16 @@ 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 ()); + atexit (close_stdout); cp_option_init (&x); diff -u -r fileutils-4.1.orig/src/install.c fileutils-4.1/src/install.c --- fileutils-4.1.orig/src/install.c Tue Jun 25 11:57:59 2002 +++ fileutils-4.1/src/install.c Tue Jun 25 11:11:19 2002 @@ -660,7 +660,7 @@ endpwent (); } else - owner_id = (uid_t) -1; + owner_id = (uid_t) getuid (); if (group_name) { @@ -678,7 +678,7 @@ endgrent (); } else - group_id = (gid_t) -1; + group_id = (gid_t) getgid (); } void diff -u -r fileutils-4.1.orig/src/ls.c fileutils-4.1/src/ls.c --- fileutils-4.1.orig/src/ls.c Tue Jun 25 11:57:59 2002 +++ fileutils-4.1/src/ls.c Tue Jun 25 11:11:19 2002 @@ -133,6 +133,8 @@ #define AUTHORS "Richard Stallman and David MacKenzie" +#include + #define obstack_chunk_alloc malloc #define obstack_chunk_free free @@ -866,6 +868,17 @@ unsigned int n_files; 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 -u -r fileutils-4.1.orig/src/mkdir.c fileutils-4.1/src/mkdir.c --- fileutils-4.1.orig/src/mkdir.c Wed Feb 21 09:05:00 2001 +++ fileutils-4.1/src/mkdir.c Tue Jun 25 11:11:19 2002 @@ -36,6 +36,8 @@ void strip_trailing_slashes (); +#include + /* The name this program was run with. */ char *program_name; @@ -86,6 +88,17 @@ 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); @@ -162,7 +175,16 @@ { const char *dir = argv[optind]; int dir_created; - fail = make_dir (dir, dir, newmode, &dir_created); + if (vsd_check_path (argv[optind], 0, R_OK | W_OK)) + { + error (0, errno, "%s", argv[optind]); + fail = 1; + } + else + { + fail = make_dir (dir, dir, newmode, &dir_created); + } + if (fail) { /* make_dir already gave a diagnostic. */ @@ -195,6 +217,16 @@ error (0, errno, _("cannot set permissions of directory %s"), quote (dir)); } + + /* FreeVSD: Need to change the ownership of the dir created to the + user executing mkdir: */ + if (fail == 0) + { + fail = chown (dir, getuid (), getgid ()); + if (fail) + error (0, errno, _("cannot set ownership of directory %s"), + quote (dir)); + } } if (fail) diff -u -r fileutils-4.1.orig/src/mv.c fileutils-4.1/src/mv.c --- fileutils-4.1.orig/src/mv.c Sat Feb 3 16:48:34 2001 +++ fileutils-4.1/src/mv.c Tue Jun 25 11:11:19 2002 @@ -41,6 +41,8 @@ #define AUTHORS "Mike Parker, David MacKenzie, and Jim Meyering" +#include + /* Initial number of entries in each hash table entry's table of inodes. */ #define INITIAL_HASH_MODULE 100 @@ -384,6 +386,16 @@ 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 ()); + atexit (close_stdout); cp_option_init (&x); diff -u -r fileutils-4.1.orig/src/remove.c fileutils-4.1/src/remove.c --- fileutils-4.1.orig/src/remove.c Sun Feb 18 16:17:32 2001 +++ fileutils-4.1/src/remove.c Tue Jun 25 11:11:19 2002 @@ -40,6 +40,8 @@ #include "quote.h" #include "remove.h" +#include + #define obstack_chunk_alloc malloc #define obstack_chunk_free free @@ -615,6 +617,15 @@ 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)) { @@ -677,6 +688,16 @@ 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; + } + if (!x->ignore_missing_files && (x->interactive || x->stdin_tty) && euidaccess (dir_name, W_OK)) { diff -u -r fileutils-4.1.orig/src/rm.c fileutils-4.1/src/rm.c --- fileutils-4.1.orig/src/rm.c Sun Apr 29 07:56:24 2001 +++ fileutils-4.1/src/rm.c Tue Jun 25 11:11:19 2002 @@ -60,6 +60,8 @@ #define AUTHORS \ "Paul Rubin, David MacKenzie, Richard Stallman, and Jim Meyering" +#include + void strip_trailing_slashes (); /* Name this program was run with. */ @@ -136,6 +138,16 @@ 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 ()); + atexit (close_stdout); rm_option_init (&x); diff -u -r fileutils-4.1.orig/src/rmdir.c fileutils-4.1/src/rmdir.c --- fileutils-4.1.orig/src/rmdir.c Sun Jul 30 17:34:44 2000 +++ fileutils-4.1/src/rmdir.c Tue Jun 25 11:11:20 2002 @@ -36,6 +36,8 @@ #define AUTHORS "David MacKenzie" +#include + #ifndef EEXIST # define EEXIST 0 #endif @@ -169,6 +171,17 @@ 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); @@ -218,8 +231,7 @@ if (verbose) error (0, 0, _("removing directory, %s"), dir); - fail = rmdir (dir); - + fail = vsd_check_path (dir, 1, R_OK | W_OK) ? 1 : rmdir (dir); if (fail) { if (ignore_fail_on_non_empty