diff -r -u fileutils-4.0.36.orig/lib/makepath.c fileutils-4.0.36/lib/makepath.c --- fileutils-4.0.36.orig/lib/makepath.c Sun Nov 5 13:10:25 2000 +++ fileutils-4.0.36/lib/makepath.c Tue Jun 25 12:30:22 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 -r -u fileutils-4.0.36.orig/src/Makefile.am fileutils-4.0.36/src/Makefile.am --- fileutils-4.0.36.orig/src/Makefile.am Fri Jun 7 15:18:55 2002 +++ fileutils-4.0.36/src/Makefile.am Tue Jun 25 12:30:22 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 -r -u fileutils-4.0.36.orig/src/Makefile.in fileutils-4.0.36/src/Makefile.in --- fileutils-4.0.36.orig/src/Makefile.in Fri Jun 7 15:18:55 2002 +++ fileutils-4.0.36/src/Makefile.in Tue Jun 25 12:30:22 2002 @@ -134,7 +134,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 -r -u fileutils-4.0.36.orig/src/chgrp.c fileutils-4.0.36/src/chgrp.c --- fileutils-4.0.36.orig/src/chgrp.c Sun Jan 7 09:19:44 2001 +++ fileutils-4.0.36/src/chgrp.c Tue Jun 25 12:30:22 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; @@ -163,6 +168,21 @@ 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; atexit (close_stdout); diff -r -u fileutils-4.0.36.orig/src/chmod.c fileutils-4.0.36/src/chmod.c --- fileutils-4.0.36.orig/src/chmod.c Sun Nov 19 16:56:33 2000 +++ fileutils-4.0.36/src/chmod.c Tue Jun 25 12:30:22 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); @@ -305,6 +324,21 @@ 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; atexit (close_stdout); diff -r -u fileutils-4.0.36.orig/src/chown-core.c fileutils-4.0.36/src/chown-core.c --- fileutils-4.0.36.orig/src/chown-core.c Sat Dec 16 18:51:27 2000 +++ fileutils-4.0.36/src/chown-core.c Tue Jun 25 12:30:22 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. */ @@ -237,6 +241,31 @@ if (chopt->force_silent == 0) error (0, errno, _("getting attributes of %s"), quote (file)); 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 diff -r -u fileutils-4.0.36.orig/src/chown.c fileutils-4.0.36/src/chown.c --- fileutils-4.0.36.orig/src/chown.c Sun Jan 7 14:47:36 2001 +++ fileutils-4.0.36/src/chown.c Tue Jun 25 12:30:22 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; @@ -153,6 +158,21 @@ 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; atexit (close_stdout); diff -r -u fileutils-4.0.36.orig/src/copy.c fileutils-4.0.36/src/copy.c --- fileutils-4.0.36.orig/src/copy.c Fri Jun 7 15:18:55 2002 +++ fileutils-4.0.36/src/copy.c Tue Jun 25 12:33:44 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,12 @@ return 1; } } + else + { + /* VSD: Then chown to the current user */ + 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 -r -u fileutils-4.0.36.orig/src/cp.c fileutils-4.0.36/src/cp.c --- fileutils-4.0.36.orig/src/cp.c Wed Jan 10 10:13:30 2001 +++ fileutils-4.0.36/src/cp.c Tue Jun 25 12:30:22 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); } @@ -710,6 +720,16 @@ 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 ()); atexit (close_stdout); diff -r -u fileutils-4.0.36.orig/src/install.c fileutils-4.0.36/src/install.c --- fileutils-4.0.36.orig/src/install.c Fri Jun 7 15:18:55 2002 +++ fileutils-4.0.36/src/install.c Tue Jun 25 12:30:22 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 -r -u fileutils-4.0.36.orig/src/ls.c fileutils-4.0.36/src/ls.c --- fileutils-4.0.36.orig/src/ls.c Fri Jun 7 15:18:55 2002 +++ fileutils-4.0.36/src/ls.c Tue Jun 25 12:30:22 2002 @@ -143,6 +143,8 @@ #define AUTHORS "Richard Stallman and David MacKenzie" +#include + #define obstack_chunk_alloc malloc #define obstack_chunk_free free @@ -861,6 +863,17 @@ 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 -r -u fileutils-4.0.36.orig/src/mkdir.c fileutils-4.0.36/src/mkdir.c --- fileutils-4.0.36.orig/src/mkdir.c Sat Dec 2 13:20:11 2000 +++ fileutils-4.0.36/src/mkdir.c Tue Jun 25 12:30:22 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); @@ -163,8 +176,18 @@ const char *dir = argv[optind]; int dir_created; int t_errno; - fail = make_dir (dir, dir, newmode, &dir_created); - t_errno = errno; + + 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); + t_errno = errno; + } + if (fail) { /* make_dir already gave a diagnostic. */ @@ -197,6 +220,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 -r -u fileutils-4.0.36.orig/src/mv.c fileutils-4.0.36/src/mv.c --- fileutils-4.0.36.orig/src/mv.c Wed Jan 10 10:23:02 2001 +++ fileutils-4.0.36/src/mv.c Tue Jun 25 12:30:22 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 @@ -383,6 +385,16 @@ 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 ()); atexit (close_stdout); diff -r -u fileutils-4.0.36.orig/src/remove.c fileutils-4.0.36/src/remove.c --- fileutils-4.0.36.orig/src/remove.c Mon Dec 25 10:44:42 2000 +++ fileutils-4.0.36/src/remove.c Tue Jun 25 12:30:22 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)) { @@ -674,6 +685,16 @@ if (!x->recursive) { error (0, 0, _("%s is a directory"), quote (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 -r -u fileutils-4.0.36.orig/src/rm.c fileutils-4.0.36/src/rm.c --- fileutils-4.0.36.orig/src/rm.c Tue May 9 22:57:43 2000 +++ fileutils-4.0.36/src/rm.c Tue Jun 25 12:30:23 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. */ @@ -130,6 +132,16 @@ 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 ()); atexit (close_stdout); diff -r -u fileutils-4.0.36.orig/src/rmdir.c fileutils-4.0.36/src/rmdir.c --- fileutils-4.0.36.orig/src/rmdir.c Sun Jul 30 17:34:44 2000 +++ fileutils-4.0.36/src/rmdir.c Tue Jun 25 12:30:23 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