Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Dec 1999 17:02:45 -0500
From:      Garance A Drosihn <drosih@rpi.edu>
To:        Robert Watson <robert+freebsd@cyrus.watson.org>
Cc:        Alfred Perlstein <bright@wintelcom.net>, Andre Albsmeier <andre.albsmeier@mchp.siemens.de>, Warner Losh <imp@village.org>, current@FreeBSD.ORG
Subject:   Re: NO! Re: [PATCHES] Two fixes for lpd/lpc for review and test
Message-ID:  <v04210100b48d8dfa3512@[128.113.24.47]>
In-Reply-To: <Pine.BSF.3.96.991224084725.28605A-100000@fledge.watson.org>
References:  <Pine.BSF.3.96.991224084725.28605A-100000@fledge.watson.org>

next in thread | previous in thread | raw e-mail | index | archive | help
At 8:55 AM -0500 12/24/99, Robert Watson wrote:
>For example, imagine that the user has a
>number of hard links to the file in question.

Okay, here's my newer version of the code, which takes into
account multiple hard links, and also makes it so the spooled
data file is owned by daemon instead of the user.  This works
fine.  At some later point I'll write an update so the spooled
data file is owned by daemon in other cases, too.

Further comments or observations welcome.  If this looks okay
I'll submit this as a new PR.

Index: lpr/lpr.c
===================================================================
RCS file: /Users/cvsdepot/lpr-fbsd/lpr/lpr.c,v
retrieving revision 1.1.1.1
diff -U5 -r1.1.1.1 lpr.c
--- lpr.c	1999/11/30 16:15:22	1.1.1.1
+++ lpr.c	1999/12/27 21:58:39
@@ -382,10 +382,69 @@
  			nact++;
  			continue;
  		}
  		if (sflag)
  			printf("%s: %s: not linked, copying 
instead\n", name, arg);
+
+		if (f) {
+			/*
+			 * The user wants the file removed after it is copied,
+			 * so see if it can be mv'ed instead of copy/unlink'ed.
+			 * This will be much faster and better than copying the
+			 * file, especially for larger files.  Can be very
+			 * useful for services like samba, pcnfs, CAP, et al.
+			 */
+			int ret, didlink;
+			struct stat statb2;
+			seteuid(euid);
+			didlink = 0;
+			/* don't do this if the user's file is a symlink */
+			if (lstat(arg, &statb) < 0)  goto nohardlink;
+			if (S_ISLNK(statb.st_mode))  goto nohardlink;
+			/* if the attempt to link fails, abandon the move */
+			if (link(arg, dfname) != 0)  goto nohardlink;
+			didlink = 1;
+			/* make sure the user hasn't tried to trick us via
+			 * any race conditions */
+			if (lstat(dfname, &statb2) < 0)    goto nohardlink;
+			if (statb.st_dev != statb2.st_dev) goto nohardlink;
+			if (statb.st_ino != statb2.st_ino) goto nohardlink;
+			/* skip if the file already had multiple hard links,
+			 * because changing the owner and access-bits would
+			 * change ALL versions of the file */
+			if (statb2.st_nlink > 2)     goto nohardlink;
+
+			/* if we can access and remove the given file without
+			 * special setuid-ness then this method is safe. */
+			seteuid(uid);
+			ret = access(dfname, R_OK);
+			if (ret == 0)
+				ret = unlink(arg);
+			seteuid(euid);
+			/* the user does not have access to read or remove
+			 * this file, so abandon the move and fall back to
+			 * the usual (copy) methods. */
+			if (ret != 0) goto nohardlink;
+
+			/* unlink of user file was successful. fixup perms,
+			 * add entries to control file, and skip copy step */
+			chown(dfname, pp->daemon_user, getegid());
+			chmod(dfname, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+			seteuid(uid);
+			if (format == 'p')
+				card('T', title ? title : arg);
+			for (i = 0; i < ncopies; i++)
+				card(format, &dfname[inchar-2]);
+			card('U', &dfname[inchar-2]);
+			card('N', arg);
+			nact++;
+			continue;
+nohardlink:
+			if (didlink) unlink(dfname);
+			seteuid(uid);           /* restore old uid */
+		} /* end: if (f) */
+
  		if ((i = open(arg, O_RDONLY)) < 0) {
  			printf("%s: cannot open %s\n", name, arg);
  		} else {
  			copy(pp, i, arg);
  			(void) close(i);
===================================================================


---
Garance Alistair Drosehn           =   gad@eclipse.acs.rpi.edu
Senior Systems Programmer          or  drosih@rpi.edu
Rensselaer Polytechnic Institute


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?v04210100b48d8dfa3512>