Perhaps something like this?  Only compile-tested.

 - todd

Index: usr.sbin/lpr/lpd/printjob.c
===================================================================
RCS file: /home/cvs/openbsd/src/usr.sbin/lpr/lpd/printjob.c,v
retrieving revision 1.49
diff -u -r1.49 printjob.c
--- usr.sbin/lpr/lpd/printjob.c 10 Dec 2013 16:38:04 -0000      1.49
+++ usr.sbin/lpr/lpd/printjob.c 18 Jan 2014 16:41:28 -0000
@@ -352,6 +352,8 @@
        (void)snprintf(&width[2], sizeof(width) - 2, "%ld", PW);
        indent[2] = '0';
        indent[3] = '\0';
+       fdev = (dev_t)-1;
+       fino = (ino_t)-1;
 
        /*
         *      read the control file for work to do
@@ -538,20 +540,30 @@
        int fd, status, serrno;
        int n, fi, fo, p[2], stopped = 0, nofile;
 
-       PRIV_START;
-       if (lstat(file, &stb) < 0 || (fi = safe_open(file, O_RDONLY, 0)) < 0) {
+       if (fdev != (dev_t)-1 && fino != (ino_t)-1) {
+               /* symbolic link */
+               PRIV_START;
+               fi = safe_open(file, O_RDONLY, 0);
+               PRIV_END;
+               if (fi != -1) {
+                       /*
+                        * The symbolic link should still point to the same file
+                        * or someone is trying to print something he shouldn't.
+                        */
+                       if (fstat(fi, &stb) == -1 ||
+                           stb.st_dev != fdev || stb.st_ino != fino) {
+                               close(fi);
+                               return(ACCESS);
+                       }
+               }
+       } else {
+               /* regular file */
+               PRIV_START;
+               fi = safe_open(file, O_RDONLY|O_NOFOLLOW, 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 he shouldn't.
-        */
-       if (S_ISLNK(stb.st_mode) && fstat(fi, &stb) == 0 &&
-           (stb.st_dev != fdev || stb.st_ino != fino))
-               return(ACCESS);
+       if (fi == -1)
+               return(ERROR);
        if (!SF && !tof) {              /* start on a fresh page */
                (void)write(ofd, FF, strlen(FF));
                tof = 1;

Reply via email to