Lpd bundles together several different errors with very different possible causes under a single error code, "ACCESS". Furthermore, while it sends E-mail when this error occurs, it doesn't syslog anything. The patch below splits the error into three different errors and logs the error to syslog in addition to sending E-mail. --- lpd/printjob.c.orig Fri Jan 7 14:08:11 2000 +++ lpd/printjob.c Fri Jan 7 14:11:19 2000 @@ -58,6 +58,8 @@ #define FILTERERR 3 #define ACCESS 4 #define UNLINK 5 +#define BADLINK 6 +#define NOSTAT 7 static dev_t fdev; /* device of file pointed to by symlink */ static ino_t fino; /* inode of file pointed to by symlink */ @@ -443,6 +445,7 @@ continue; default: /* some file to print */ + cp = NULL; switch (i = print(line[0], line+1)) { case ERROR: if (bombed == OK) @@ -452,8 +455,16 @@ (void) fclose(cfp); return(REPRINT); case FILTERERR: + if (! cp) cp = "FILTERERR"; case ACCESS: + if (! cp) cp = "ACCESS"; + case NOSTAT: + if (! cp) cp = "NOSTAT"; + case BADLINK: + if (! cp) cp = "BADLINK"; bombed = i; + syslog(LOG_ERR, "%s: %s: %s error on line \"%s\"", + printer, file, cp, line); sendmail(logname, bombed); } title[0] = '\0'; @@ -535,7 +546,13 @@ /* Open the file as the user. */ - if (lstat(file, &stb) < 0 || (fi = open(file, O_RDONLY)) < 0) { + if (lstat(file, &stb) < 0) { + seteuid(euid); + setegid(egid); + return(NOSTAT); + } + + if ((fi = open(file, O_RDONLY)) < 0) { seteuid(euid); setegid(egid); return(ACCESS); @@ -552,7 +569,7 @@ */ if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(fi, &stb) == 0 && (stb.st_dev != fdev || stb.st_ino != fino)) - return(ACCESS); + return(BADLINK); if (!SF && !tof) { /* start on a fresh page */ (void) write(ofd, FF, strlen(FF)); tof = 1; @@ -990,7 +1007,8 @@ (void) fclose(cfp); return(REPRINT); case ACCESS: - sendmail(logname, ACCESS); + case NOSTAT: + sendmail(logname, sendresult); case ERROR: err = ERROR; } @@ -1087,7 +1105,13 @@ /* Open the file as the user. */ - if (lstat(file, &stb) < 0 || (f = open(file, O_RDONLY)) < 0) { + if (lstat(file, &stb) < 0) { + seteuid(euid); + setegid(egid); + return(NOSTAT); + } + + if ((f = open(file, O_RDONLY)) < 0) { seteuid(euid); setegid(egid); return(ACCESS); @@ -1105,7 +1129,7 @@ */ if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(f, &stb) == 0 && (stb.st_dev != fdev || stb.st_ino != fino)) - return(ACCESS); + return(BADLINK); (void) snprintf(buf, sizeof(buf), "%c%d %s\n", type, stb.st_size, file); amt = strlen(buf); for (i = 0; ; i++) { @@ -1371,10 +1395,18 @@ (void) fclose(fp); cp = "FILTERERR"; break; - case ACCESS: + case BADLINK: printf("\nwas not printed because it was not linked to the original file\n"); - cp = "ACCESS"; + cp = "BADLINK"; break; + case ACCESS: + printf("\nwas not printed because the file could not be accessed\n"); + cp = "ACCESS"; + break; + case NOSTAT: + printf("\nwas not printed because the daemon could not stat the file\n"); + cp = "NOSTAT"; + break; case UNLINK: printf("\nwas not unlinked: permission denied\n"); break;
Created attachment 109 [details] new patch for lpr-0.50
Thanks, in CVS.