From owner-freebsd-audit Thu Jun 21 15: 1:44 2001 Delivered-To: freebsd-audit@freebsd.org Received: from mail.rpi.edu (mail.rpi.edu [128.113.22.40]) by hub.freebsd.org (Postfix) with ESMTP id EF12337B403 for ; Thu, 21 Jun 2001 15:01:38 -0700 (PDT) (envelope-from drosih@rpi.edu) Received: from [128.113.24.47] (gilead.acs.rpi.edu [128.113.24.47]) by mail.rpi.edu (8.11.3/8.11.3) with ESMTP id f5LM1bH59408; Thu, 21 Jun 2001 18:01:37 -0400 Mime-Version: 1.0 X-Sender: drosih@mail.rpi.edu Message-Id: In-Reply-To: References: Date: Thu, 21 Jun 2001 18:01:31 -0400 To: freebsd-print@bostonradio.org From: Garance A Drosihn Subject: Re: Patch: smarter 'lpc clean', new 'lpc tclean' Cc: freebsd-audit@FreeBSD.ORG Content-Type: text/plain; charset="us-ascii" ; format="flowed" Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG At 8:53 PM -0400 6/18/01, Garance A Drosihn wrote: >Main goals of this update to lpc (part of lpr & friends): > > 1) make 'lpc clean' somewhat safer > 2) add an 'lpc tclean', which allows one to see what files would be > removed *if* an 'lpc clean' is done. Note that 'lpc tclean' is > not a privileged command, since it won't actually remove anything. > 3) have 'lpc clean' and 'lpc tclean' also look for core files > in spool directories. > 4) make 'lpc clean' somewhat prettier and more informative. > 5) get rid of some more compile-type warnings when BDECFLAGS is used > (mainly by fixing up cmdtab.c). > 6) as part of creating 'lpc clean' from 'lpc tclean', make it possible > for "generic printer" routines to have an initialization routine > which can set initial values of global variables, or even do some > processing of command-line options. It can also set a "wrap-up" > routine, which could be used to print summary information. > >This is cross-posted to freebsd-audit since the 'lpc' command is >setgid daemon. (and at least at RPI, it's often run via 'sudo'). It >wouldn't hurt to be a little extra paranoid while eyeing these changes... I have a newer version of the update available at: http://freefour.acs.rpi.edu/pub/bsdlpr/lpc-clean.diff and http://people.freebsd.org/~gad/lpr/lpc-clean.diff It includes a change for the man page. Most of the rest of the update is just minor cleanups from my previous version. I hope to commit this to current this weekend, assuming no one has any feedback about it. The update is a little over 600 lines, so I wasn't sure if I should post the entire thing all over again. The 'unlinkf' routine has seen the most change, so here's just that part of the patch for people to eyeball: static void unlinkf(char *name) { + struct stat stbuf; + double agemod, agestat; + int res; + char linkbuf[BUFSIZ]; + + /* + * We have to use lstat() instead of stat(), in case this is a df* + * "file" which is really a symlink due to 'lpr -s' processing. In + * that case, we need to check the last-mod time of the symlink, and + * not the file that the symlink is pointed at. + */ seteuid(euid); - if (unlink(name) < 0) - printf("\tcannot remove %s\n", name); - else - printf("\tremoved %s\n", name); + res = lstat(name, &stbuf); seteuid(uid); + if (res < 0) { + printf("\terror return from stat(%s):\n", name); + printf("\t %s\n", strerror(errno)); + return; + } + + agemod = difftime(cln_now, stbuf.st_mtime); + agestat = difftime(cln_now, stbuf.st_ctime); + if (cln_debug) { + /* this debugging-aid probably is not needed any more... */ + printf("\t\t modify age=%g secs, stat age=%g secs\n", + agemod, agestat); + } + if ((agemod <= cln_minage) && (agestat <= cln_minage)) + return; + + /* + * if this file is a symlink, then find out the target of the + * symlink before unlink-ing the file itself + */ + if (S_ISLNK(stbuf.st_mode)) { + seteuid(euid); + res = readlink(name, linkbuf, sizeof(linkbuf)); + seteuid(uid); + if (res < 0) { + printf("\terror return from readlink(%s):\n", name); + printf("\t %s\n", strerror(errno)); + return; + } + if (res == sizeof(linkbuf)) + res--; + linkbuf[res] = '\0'; + } + + cln_filecnt++; + cln_sizecnt += stbuf.st_size; + + if (cln_testonly) { + printf("\twould remove %s\n", name); + if (S_ISLNK(stbuf.st_mode)) { + printf("\t (which is a symlink to %s)\n", linkbuf); + } + } else { + seteuid(euid); + res = unlink(name); + seteuid(uid); + if (res < 0) + printf("\tcannot remove %s (!)\n", name); + else + printf("\tremoved %s\n", name); + /* XXX + * Note that for a df* file, this code should also check to see + * if it is a symlink to some other file, and if the original + * lpr command included '-r' ("remove file"). Of course, this + * code would not be removing the df* file unless there was no + * matching cf* file, and without the cf* file it is currently + * impossible to determine if '-r' had been specified... + * + * As a result of this quandary, we may be leaving behind a + * user's file that was supposed to have been removed after + * being printed. This may effect services such as CAP or + * samba, if they were configured to use 'lpr -r', and if + * datafiles are not being properly removed. + */ + if (S_ISLNK(stbuf.st_mode)) { + printf("\t (which was a symlink to %s)\n", linkbuf); + } + } } /* -- Garance Alistair Drosehn = gad@eclipse.acs.rpi.edu Senior Systems Programmer or gad@freebsd.org Rensselaer Polytechnic Institute or drosih@rpi.edu To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message