Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 May 2000 20:40:05 -0700 (PDT)
From:      Garance A Drosehn <gad@freefour.acs.rpi.edu>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/16124: [PATCH] Enhancement for 'lpr -r'
Message-ID:  <200005100340.UAA83881@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/16124; it has been noted by GNATS.

From: Garance A Drosehn <gad@freefour.acs.rpi.edu>
To: freebsd-gnats-submit@FreeBSD.org
Cc: gad@eclipse.acs.rpi.edu
Subject: Re: bin/16124: [PATCH] Enhancement for 'lpr -r'
Date: Tue, 9 May 2000 23:29:54 -0400 (EDT)

 I wanted to improve some of the comments in this update, and thought
 I could justify that by also getting it bit closer to 'man style'
 conventions.  Here is the spruced-up version.
 
 I am not sure the patch will come thru the email correctly, so I'll
 also mention that it's available at:
 
 ftp://freefour.acs.rpi.edu/pub/bsdlpr/lpr-mv.diff
 
 [start] = = = = = = = = = = = = = = = = = [start]
 --- lpr.c.orig	Wed Jan 19 09:25:08 2000
 +++ lpr.c	Tue May  9 22:34:33 2000
 @@ -384,6 +384,81 @@
  		}
  		if (sflag)
  			printf("%s: %s: not linked, copying instead\n", name, arg);
 +
 +		if (f) {
 +			/*
 +			 * The user wants the file removed after it is copied
 +			 * to the spool area, so see if the file can be moved
 +			 * instead of copy/unlink'ed.  This is much faster and
 +			 * uses less spool space than copying the file.  This
 +			 * can be very significant when running services like
 +			 * samba, pcnfs, CAP, et al.
 +			 */
 +			int ret, didlink;
 +			struct stat statb1, statb2;
 +			seteuid(euid);
 +			didlink = 0;
 +			/*
 +			 * There are several things to check to avoid any
 +			 * security issues.  Some of these are redundant
 +			 * under BSD's, but are necessary when lpr is built
 +			 * under some other OS's (which I do do...)
 +			 */
 +			if (lstat(arg, &statb1) < 0)
 +				goto nohardlink;
 +			if (S_ISLNK(statb1.st_mode))
 +				goto nohardlink;
 +			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 (statb1.st_dev != statb2.st_dev)
 +				goto nohardlink;
 +			if (statb1.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 original file
 +			 * without special setuid-ness then this method is
 +			 * safe.  Otherwise, abandon the move and fall back
 +			 * to the (usual) copy method.
 +			 */
 +			seteuid(uid);
 +			ret = access(dfname, R_OK);
 +			if (ret == 0)
 +				ret = unlink(arg);
 +			seteuid(euid);
 +			if (ret != 0)
 +				goto nohardlink;
 +			/*
 +			 * unlink of user file was successful.  Change the
 +			 * owner and permissions, add entries to the control
 +			 * file, and skip the file copying 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 {
 [end] = = = = = = = = = = = = = = = = = = = = = [end]
 


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




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