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>