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>