diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2002-06-08 01:53:44 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2002-06-08 01:53:44 +0000 |
commit | 16c2ffab14daba8ec85369749a7f5da0849d2d55 (patch) | |
tree | 913bd4afb3022d2751aea865e7a9a0c6d046fff1 /usr.sbin/lpr/lpd | |
parent | f1da2a2b8fda92ebc29cd063f882352d44750caf (diff) |
Remove setuid root from lp*. lpr needs to be setuid daemon so the
files it creates are not owned by the user spooling them but the
others (lpc, lpq, lprm) can get away with setgid daemon. lpd runs
as user daemon for most things, only changing its uid to 0 for
things that must be done as root.
For the time being, don't require connections to come from a reserved
port since lpq/lpr/lprm can't acquire that w/o setuid root. In the
near future we will have a mechanism for select non-root processes
to grab reserved ports.
The upshot of this is that spool directories must be writable by
group daemon and the files within the spool dirs must be owned by
daemon.
Diffstat (limited to 'usr.sbin/lpr/lpd')
-rw-r--r-- | usr.sbin/lpr/lpd/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/lpr/lpd/lpd.c | 81 | ||||
-rw-r--r-- | usr.sbin/lpr/lpd/printjob.c | 140 | ||||
-rw-r--r-- | usr.sbin/lpr/lpd/recvjob.c | 24 |
4 files changed, 164 insertions, 85 deletions
diff --git a/usr.sbin/lpr/lpd/Makefile b/usr.sbin/lpr/lpd/Makefile index 5698aed8d73..5d64e87885e 100644 --- a/usr.sbin/lpr/lpd/Makefile +++ b/usr.sbin/lpr/lpd/Makefile @@ -1,11 +1,13 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.3 2002/05/20 23:13:50 millert Exp $ +# $OpenBSD: Makefile,v 1.4 2002/06/08 01:53:43 millert Exp $ PROG= lpd CFLAGS+=-I${.CURDIR}/../common_source MAN= lpd.8 SRCS= lpd.c printjob.c recvjob.c displayq.c rmjob.c startdaemon.c \ lpdchar.c common.c key.c modes.c ttcompat.c common_vars.c +BINGRP= daemon +BINMODE=2550 .PATH: ${.CURDIR}/../common_source .include "../../Makefile.inc" diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c index fe6034e3113..e731fda086b 100644 --- a/usr.sbin/lpr/lpd/lpd.c +++ b/usr.sbin/lpr/lpd/lpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lpd.c,v 1.32 2002/05/28 18:17:22 millert Exp $ */ +/* $OpenBSD: lpd.c,v 1.33 2002/06/08 01:53:43 millert Exp $ */ /* $NetBSD: lpd.c,v 1.33 2002/01/21 14:42:29 wiz Exp $ */ /* @@ -45,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)lpd.c 8.7 (Berkeley) 5/10/95"; #else -static const char rcsid[] = "$OpenBSD: lpd.c,v 1.32 2002/05/28 18:17:22 millert Exp $"; +static const char rcsid[] = "$OpenBSD: lpd.c,v 1.33 2002/06/08 01:53:43 millert Exp $"; #endif #endif /* not lint */ @@ -66,16 +66,18 @@ static const char rcsid[] = "$OpenBSD: lpd.c,v 1.32 2002/05/28 18:17:22 millert * remove jobs from the queue. * * Strategy to maintain protected spooling area: - * 1. Spooling area is writable only by daemon and spooling group - * 2. lpr runs setuid root and setgrp spooling group; it uses - * root to access any file it wants (verifying things before - * with an access call) and group id to know how it should - * set up ownership of files in the spooling area. - * 3. Files in spooling area are owned by root, group spooling - * group, with mode 660. - * 4. lpd, lpq and lprm run setuid daemon and setgrp spooling group to - * access files and printer. Users can't get to anything - * w/o help of lpq and lprm programs. + * 1. Spooling area is writable only by root and the group daemon. + * 2. Files in spooling area are owned by user daemon, group daemon, + * and are mode 660. + * 3. lpd runs as root but spends most of its time with its effective + * uid and gid set to the uid/gid specified in the passwd entry for + * DEFUID (1, aka daemon). + * 4. lpr runs setuid daemon and setgrp daemon; it opens + * files to be printed with its real uid/gid and writes to + * the spool dir with its effective uid/gid (i.e. daemon). + * 5. lpc, lpr and lprm run setgrp daemon. + * + * Users can't touch the spool w/o the help of one of the lp* programs. */ #include <sys/param.h> @@ -94,6 +96,7 @@ static const char rcsid[] = "$OpenBSD: lpd.c,v 1.32 2002/05/28 18:17:22 millert #include <errno.h> #include <fcntl.h> #include <netdb.h> +#include <pwd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -137,6 +140,7 @@ int main(int argc, char **argv) { fd_set defreadfds; + struct passwd *pw; struct sockaddr_un un, fromunix; struct sockaddr_storage frominet; sigset_t mask, omask; @@ -148,14 +152,24 @@ main(int argc, char **argv) const char *port = "printer"; char *cp; - euid = geteuid(); /* these shouldn't be different */ - uid = getuid(); - options = check_options = 0; - gethostname(host, sizeof(host)); - - if (euid != 0) + if (geteuid() != 0) errx(1, "must run as root"); + /* + * We want to run with euid of daemon most of the time. + */ + if ((pw = getpwuid(DEFUID)) == NULL) + errx(1, "daemon uid (%d) not in password file", DEFUID); + real_uid = pw->pw_uid; + real_gid = pw->pw_gid; + effective_uid = 0; + effective_gid = getegid(); + PRIV_END; /* run as daemon for most things */ + + check_options = LPD_NOPORTCHK; /* XXX - lp* not setuid root */ + options = 0; + gethostname(host, sizeof(host)); + while ((i = getopt(argc, argv, "b:cdln:rsw:W")) != -1) { switch (i) { case 'b': @@ -240,7 +254,9 @@ main(int argc, char **argv) openlog("lpd", LOG_PID, LOG_LPR); syslog(LOG_INFO, "restarted"); (void)umask(0); + PRIV_START; lfd = open(_PATH_MASTERLOCK, O_WRONLY|O_CREAT|O_EXLOCK|O_NONBLOCK, 0644); + PRIV_END; if (lfd < 0) { if (errno == EWOULDBLOCK) /* active daemon present */ exit(0); @@ -262,7 +278,9 @@ main(int argc, char **argv) * Restart all the printers. */ startup(); + PRIV_START; (void)unlink(_PATH_SOCKETNAME); + PRIV_END; funix = socket(AF_LOCAL, SOCK_STREAM, 0); if (funix < 0) { syslog(LOG_ERR, "socket: %m"); @@ -287,10 +305,12 @@ main(int argc, char **argv) #ifndef SUN_LEN #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) #endif + PRIV_START; if (bind(funix, (struct sockaddr *)&un, SUN_LEN(&un)) < 0) { syslog(LOG_ERR, "ubind: %m"); exit(1); } + PRIV_END; (void)umask(0); sigprocmask(SIG_SETMASK, &omask, NULL); FD_ZERO(&defreadfds); @@ -438,6 +458,7 @@ mcleanup(int signo) if (lflag) syslog_r(LOG_INFO, &sdata, "exiting"); + PRIV_START; unlink(_PATH_SOCKETNAME); unlink(_PATH_MASTERLOCK); _exit(0); @@ -584,8 +605,7 @@ doit(void) static void startup(void) { - char *buf; - char *cp; + char *buf, *cp; /* * Restart the daemons. @@ -622,6 +642,7 @@ startup(void) /* * Make sure there's some work to do before forking off a child + * XXX - could be common w/ lpq */ static int ckqueue(char *cap) @@ -632,13 +653,14 @@ ckqueue(char *cap) if (cgetstr(cap, "sd", &spooldir) == -1) spooldir = _PATH_DEFSPOOL; - if ((dirp = opendir(spooldir)) == NULL) + dirp = opendir(spooldir); + if (dirp == NULL) return (-1); while ((d = readdir(dirp)) != NULL) { - if (d->d_name[0] != 'c' || d->d_name[1] != 'f') - continue; /* daemon control files only */ - closedir(dirp); - return (1); /* found something */ + if (d->d_name[0] == 'c' && d->d_name[1] == 'f') { + closedir(dirp); + return (1); /* found a cf file */ + } } closedir(dirp); return (0); @@ -710,7 +732,9 @@ chkhost(struct sockaddr *f, int check_opts) if (good == 0) fatal("address for your hostname (%s) not matched", host); setproctitle("serving %s", from); + PRIV_START; hostf = fopen(_PATH_HOSTSEQUIV, "r"); + PRIV_END; again: if (hostf) { if (__ivaliduser_sa(hostf, f, f->sa_len, DUMMY, DUMMY) == 0) { @@ -721,7 +745,9 @@ again: } if (first == 1) { first = 0; + PRIV_START; hostf = fopen(_PATH_HOSTSLPD, "r"); + PRIV_END; goto again; } fatal("Your host does not have line printer access"); @@ -796,7 +822,10 @@ socksetup(int af, int options, const char *port) close (*s); continue; } - if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) { + PRIV_START; + error = bind(*s, r->ai_addr, r->ai_addrlen); + PRIV_END; + if (error < 0) { syslog(LOG_DEBUG, "bind(): %m"); close (*s); continue; diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c index a1578c9e43a..8e0bce7da8e 100644 --- a/usr.sbin/lpr/lpd/printjob.c +++ b/usr.sbin/lpr/lpd/printjob.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printjob.c,v 1.32 2002/05/20 23:13:50 millert Exp $ */ +/* $OpenBSD: printjob.c,v 1.33 2002/06/08 01:53:43 millert Exp $ */ /* $NetBSD: printjob.c,v 1.31 2002/01/21 14:42:30 wiz Exp $ */ /* @@ -72,6 +72,7 @@ static const char sccsid[] = "@(#)printjob.c 8.7 (Berkeley) 5/10/95"; #include <stdlib.h> #include <stdarg.h> #include <ctype.h> + #include "lp.h" #include "lp.local.h" #include "pathnames.h" @@ -94,13 +95,13 @@ static const char sccsid[] = "@(#)printjob.c 8.7 (Berkeley) 5/10/95"; static dev_t fdev; /* device of file pointed to by symlink */ static ino_t fino; /* inode of file pointed to by symlink */ static FILE *cfp; /* control file */ -static int child; /* id of any filters */ +static pid_t child; /* pid of any filters */ static int lfd; /* lock file descriptor */ static int ofd; /* output filter file descriptor */ -static int ofilter; /* id of output filter, if any */ +static pid_t ofilter; /* pid of output filter, if any */ static int pfd; /* prstatic inter file descriptor */ -static int pid; /* pid of lpd process */ -static int prchild; /* id of pr process */ +static pid_t pid; /* pid of lpd process */ +static pid_t prchild; /* pid of pr process */ static char title[80]; /* ``pr'' title */ static int tof; /* true if at top of form */ @@ -118,7 +119,7 @@ static char width[10] = "-w"; /* page width in static characters */ static void abortpr(int); static void banner(char *, char *); -static int dofork(int); +static pid_t dofork(int); static int dropit(int); static void init(void); static void openpr(void); @@ -144,18 +145,27 @@ printjob(void) struct stat stb; struct queue *q, **qp; struct queue **queue; - int i, nitems; + int i, fd, nitems; off_t pidoff; int errcnt, count = 0; init(); /* set up capabilities */ (void)write(STDOUT_FILENO, "", 1); /* ack that daemon is started */ - (void)close(STDERR_FILENO); /* set up log file */ - if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) { + PRIV_START; + fd = open(LF, O_WRONLY|O_APPEND, 0664); /* set up log file */ + PRIV_END; + if (fd < 0) { syslog(LOG_ERR, "%s: %m", LF); - (void)open(_PATH_DEVNULL, O_WRONLY); + if ((fd = open(_PATH_DEVNULL, O_WRONLY)) < 0) + exit(1); + } + if (fd != STDERR_FILENO) { + if (dup2(fd, STDERR_FILENO) < 0) { + syslog(LOG_ERR, "dup2: %m"); + exit(1); + } + close(fd); } - setgid(getegid()); pid = getpid(); /* for use with lprm */ setpgrp(0, pid); signal(SIGHUP, abortpr); @@ -163,28 +173,23 @@ printjob(void) signal(SIGQUIT, abortpr); signal(SIGTERM, abortpr); - (void)mktemp(tempfile); /* safe */ - - /* - * uses short form file names - */ + /* so we can use short form file names */ if (chdir(SD) < 0) { syslog(LOG_ERR, "%s: %m", SD); exit(1); } - if (stat(LO, &stb) == 0 && (stb.st_mode & S_IXUSR)) - exit(0); /* printing disabled */ - lfd = open(LO, O_WRONLY|O_CREAT, 0644); + + (void)mktemp(tempfile); /* safe */ + + lfd = safe_open(LO, O_WRONLY|O_CREAT|O_NOFOLLOW|O_EXLOCK, 0640); if (lfd < 0) { - syslog(LOG_ERR, "%s: %s: %m", printer, LO); - exit(1); - } - if (flock(lfd, LOCK_EX|LOCK_NB) < 0) { if (errno == EWOULDBLOCK) /* active daemon present */ exit(0); syslog(LOG_ERR, "%s: %s: %m", printer, LO); exit(1); } + if (fstat(lfd, &stb) == 0 && (stb.st_mode & S_IXUSR)) + exit(0); /* printing disabled */ ftruncate(lfd, 0); /* * write process id for others to know @@ -208,10 +213,14 @@ printjob(void) if (nitems == 0) /* no work to do */ exit(0); if (stb.st_mode & S_IXOTH) { /* reset queue flag */ - if (fchmod(lfd, stb.st_mode & 0776) < 0) + stb.st_mode &= ~S_IXOTH; + if (fchmod(lfd, stb.st_mode & 0777) < 0) syslog(LOG_ERR, "%s: %s: %m", printer, LO); } + PRIV_START; openpr(); /* open printer or remote */ + PRIV_END; + again: /* * we found something to do now do it -- @@ -246,7 +255,8 @@ again: if (stb.st_mode & S_IXOTH) { for (free((char *) q); nitems--; free((char *) q)) q = *qp++; - if (fchmod(lfd, stb.st_mode & 0776) < 0) + stb.st_mode &= ~S_IXOTH; + if (fchmod(lfd, stb.st_mode & 0777) < 0) syslog(LOG_WARNING, "%s: %s: %m", printer, LO); break; @@ -267,16 +277,20 @@ again: (void)close(pfd); /* close printer */ if (ftruncate(lfd, pidoff) < 0) syslog(LOG_WARNING, "%s: %s: %m", printer, LO); + PRIV_START; openpr(); /* try to reopen printer */ + PRIV_END; goto restart; } else { syslog(LOG_WARNING, "%s: job could not be %s (%s)", printer, remote ? "sent to remote host" : "printed", q->q_name); if (i == REPRINT) { /* ensure we don't attempt this job again */ + PRIV_START; (void)unlink(q->q_name); q->q_name[0] = 'd'; (void)unlink(q->q_name); + PRIV_END; if (logname[0]) sendmail(logname, FATALERR); } @@ -323,15 +337,18 @@ char ifonts[4][40] = { static int printit(char *file) { - int i; + int i, fd; char *cp; int bombed = OK; /* * open control file; ignore if no longer there. */ - if ((cfp = fopen(file, "r")) == NULL) { + fd = safe_open(file, O_RDONLY|O_NOFOLLOW, 0); + if (fd < 0 || (cfp = fdopen(fd, "r")) == NULL) { syslog(LOG_INFO, "%s: %s: %m", printer, file); + if (fd >= 0) + close(fd); return(OK); } /* @@ -521,14 +538,19 @@ pass2: static int print(int format, char *file) { - FILE *fp; - int status, serrno; + ssize_t nread; struct stat stb; + pid_t pid; char *prog, *av[15], buf[BUFSIZ]; - int n, fi, fo, pid, p[2], stopped = 0, nofile; + int fd, status, serrno; + int n, fi, fo, p[2], stopped = 0, nofile; - if (lstat(file, &stb) < 0 || (fi = open(file, O_RDONLY)) < 0) + PRIV_START; + if (lstat(file, &stb) < 0 || (fi = safe_open(file, O_RDONLY, 0)) < 0) { + PRIV_END; return(ERROR); + } + PRIV_END; /* * Check to see if data file is a symbolic link. If so, it should * still point to the same file or someone is trying to print @@ -590,7 +612,7 @@ print(int format, char *file) * For now, treat this as a plain-text file, and assume * the standard LPF_INPUT filter will recognize that it * is postscript and know what to do with it. These - * 'o'-file requests could come from MacOS 10.1 systems. + * 'o'-file requests could come from MacOS X systems. */ /* FALLTHROUGH */ case 'f': /* print plain text file */ @@ -618,7 +640,7 @@ print(int format, char *file) case 'n': /* print ditroff output */ case 'd': /* print tex output */ (void)unlink(".railmag"); - if ((fo = creat(".railmag", FILMOD)) < 0) { + if ((fo = open(".railmag", O_CREAT|O_WRONLY|O_EXCL, FILMOD)) < 0) { syslog(LOG_ERR, "%s: cannot create .railmag", printer); (void)unlink(".railmag"); } else { @@ -697,7 +719,7 @@ start: dup2(fi, 0); dup2(fo, 1); unlink(tempfile); - n = open(tempfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0664); + n = open(tempfile, O_WRONLY|O_CREAT|O_EXCL, 0664); if (n >= 0) dup2(n, 2); closelog(); @@ -729,10 +751,11 @@ start: tof = 0; /* Copy filter output to "lf" logfile */ - if ((fp = fopen(tempfile, "r")) != NULL) { - while (fgets(buf, sizeof(buf), fp)) - fputs(buf, stderr); - fclose(fp); + fd = safe_open(tempfile, O_RDONLY|O_NOFOLLOW, 0); + if (fd >= 0) { + while ((nread = read(fd, buf, sizeof(buf))) > 0) + (void)write(STDERR_FILENO, buf, nread); + close(fd); } if (!WIFEXITED(status)) { @@ -750,7 +773,7 @@ start: return(ERROR); default: syslog(LOG_WARNING, "%s: filter '%c' exited (retcode=%d)", - printer, format, WEXITSTATUS(status)); + printer, format, WEXITSTATUS(status)); return(FILTERERR); } } @@ -763,13 +786,12 @@ start: static int sendit(char *file) { - int i, err = OK; + int fd, i, err = OK; char *cp, last[BUFSIZ]; - /* - * open control file - */ - if ((cfp = fopen(file, "r")) == NULL) + /* open control file */ + fd = safe_open(file, O_RDONLY|O_NOFOLLOW, 0); + if (fd < 0 || (cfp = fdopen(fd, "r")) == NULL) return(OK); /* * read the control file for work to do @@ -853,8 +875,12 @@ sendfile(int type, char *file) char buf[BUFSIZ]; int sizerr, resp; - if (lstat(file, &stb) < 0 || (f = open(file, O_RDONLY)) < 0) + PRIV_START; + if (lstat(file, &stb) < 0 || (f = safe_open(file, O_RDONLY, 0)) < 0) { + PRIV_END; return(ERROR); + } + PRIV_END; /* * Check to see if data file is a symbolic link. If so, it should * still point to the same file or someone is trying to print something @@ -1140,11 +1166,12 @@ sendmail(char *user, int bombed) /* * dofork - fork with retries on failure */ -static int +static pid_t dofork(int action) { - int i, pid; struct passwd *pw; + pid_t pid; + int i; for (i = 0; i < 20; i++) { if ((pid = fork()) < 0) { @@ -1155,6 +1182,7 @@ dofork(int action) * Child should run as daemon instead of root */ if (pid == 0) { + PRIV_START; pw = getpwuid(DU); if (pw == 0) { syslog(LOG_ERR, "uid %ld not in password file", @@ -1279,6 +1307,7 @@ init(void) /* * Acquire line printer or remote connection. + * XXX - should push down privs in here */ static void openpr(void) @@ -1477,7 +1506,7 @@ static void setty(void) { struct info i; - char **argv, **ap, *p, *val; + char **argv, **ap, **ep, *p, *val; i.fd = pfd; i.set = i.wset = 0; @@ -1514,19 +1543,26 @@ setty(void) syslog(LOG_INFO, "%s: ioctl(TIOCGWINSZ): %m", printer); - argv = (char **)calloc(256, sizeof(char *)); + argv = (char **)malloc(256 * sizeof(char *)); if (argv == NULL) { - syslog(LOG_ERR, "%s: calloc: %m", printer); + syslog(LOG_ERR, "%s: malloc: %m", printer); exit(1); } p = strdup(MS); ap = argv; + ep = argv + 255; while ((val = strsep(&p, " \t,")) != NULL) { if ((*ap++ = strdup(val)) == NULL) { syslog(LOG_ERR, "%s: strdup: %m", printer); exit(1); } + if (ap == ep) { + syslog(LOG_ERR, "%s: too many \"ms\" entries", + printer); + exit(1); + } } + *ap = NULL; for (; *argv; ++argv) { if (ksearch(&argv, &i)) @@ -1573,8 +1609,8 @@ pstatus(const char *msg, ...) va_start(ap, msg); umask(0); - fd = open(ST, O_WRONLY|O_CREAT, 0664); - if (fd < 0 || flock(fd, LOCK_EX) < 0) { + fd = open(ST, O_WRONLY|O_CREAT|O_NOFOLLOW|O_EXLOCK, 0660); + if (fd < 0) { syslog(LOG_ERR, "%s: %s: %m", printer, ST); exit(1); } diff --git a/usr.sbin/lpr/lpd/recvjob.c b/usr.sbin/lpr/lpd/recvjob.c index 2d2d9b0c0cc..4962d4175ec 100644 --- a/usr.sbin/lpr/lpd/recvjob.c +++ b/usr.sbin/lpr/lpd/recvjob.c @@ -1,4 +1,4 @@ -/* $OpenBSD: recvjob.c,v 1.20 2002/05/20 23:13:50 millert Exp $ */ +/* $OpenBSD: recvjob.c,v 1.21 2002/06/08 01:53:43 millert Exp $ */ /* $NetBSD: recvjob.c,v 1.14 2001/12/04 22:52:44 christos Exp $ */ /* @@ -45,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)recvjob.c 8.2 (Berkeley) 4/27/95"; #else -static const char rcsid[] = "$OpenBSD: recvjob.c,v 1.20 2002/05/20 23:13:50 millert Exp $"; +static const char rcsid[] = "$OpenBSD: recvjob.c,v 1.21 2002/06/08 01:53:43 millert Exp $"; #endif #endif /* not lint */ @@ -113,10 +113,12 @@ recvjob(void) LO = DEFLOCK; (void)close(2); /* set up log file */ + PRIV_START; if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) { syslog(LOG_ERR, "%s: %m", LF); (void)open(_PATH_DEVNULL, O_WRONLY); } + PRIV_END; if (chdir(SD) < 0) frecverr("%s: %s: %m", printer, SD); @@ -128,6 +130,7 @@ recvjob(void) } } else if (stat(SD, &stb) < 0) frecverr("%s: %s: %m", printer, SD); + minfree = 2 * read_number("minfree"); /* scale KB to 512 blocks */ signal(SIGTERM, rcleanup); signal(SIGPIPE, rcleanup); @@ -191,12 +194,22 @@ readjob(void) (void)write(STDOUT_FILENO, "\2", 1); continue; } + /* + * XXX + * We blindly believe what the remote host puts + * for the path to the df file. In general this + * is OK since we don't allow paths with '/' in + * them. Still, it would be better to sanity + * check the cf file sent to us and make the + * df name match the cf name we used. That way + * we avoid any possible collisions. + */ if (!readfile(tfname, size)) { rcleanup(0); continue; } if (link(tfname, cp) < 0) - frecverr("%s: %m", tfname); + frecverr("link %s %s: %m", tfname, cp); (void)unlink(tfname); tfname[0] = '\0'; nfiles++; @@ -233,8 +246,7 @@ readfile(char *file, int size) int i, j, amt; int fd, err; - fd = open(file, O_CREAT|O_EXCL|O_WRONLY, FILMOD); - if (fd < 0) + if ((fd = open(file, O_CREAT|O_EXCL|O_WRONLY, FILMOD)) < 0) frecverr("readfile: %s: illegal path name: %m", file); ack(); err = 0; @@ -311,7 +323,7 @@ read_number(char *fn) if ((fp = fopen(fn, "r")) == NULL) return (0); - if (fgets(lin, 80, fp) == NULL) { + if (fgets(lin, sizeof(lin), fp) == NULL) { fclose(fp); return (0); } |