]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Adds a JobProtection config option to hfaxd. This option allows for the
authorAidan Van Dyk <aidan@ifax.com>
Mon, 12 Jun 2006 18:28:53 +0000 (18:28 +0000)
committerAidan Van Dyk <aidan@ifax.com>
Mon, 12 Jun 2006 18:28:53 +0000 (18:28 +0000)
send/done queues to be kept "private", by giving any combination of onwer/admin/others
access to it or not.

This patch exposes a bit of the internal hfaxd "protection" mechanism by
exposing the octal value for admins to set.  It would probably be better to hid
the value and just have some set of values for JobProtection that setConfigItem()
should match and then setting the octal value internally.

hfaxd/FileSystem.c++
hfaxd/HylaFAXServer.c++
hfaxd/HylaFAXServer.h
hfaxd/Jobs.c++
man/hfaxd.1m

index 618ffd1da199e75c62049404b03310cb0b4f6f22..f05859544b9d167bdfda42bcb889b60b713b279a 100644 (file)
@@ -138,63 +138,63 @@ HylaFAXServer::mdtmCmd(const char* pathname)
  */
 SpoolDir HylaFAXServer::dirs[] = {
 { "/status/",  false, false, false, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listStatus,  &HylaFAXServer::listStatusFile,
   &HylaFAXServer::nlstStatus,  &HylaFAXServer::nlstUnixFile, },
 { "/sendq/",   false, false, false, 0,
-  HylaFAXServer::isVisibleSendQFile,
+  &HylaFAXServer::isVisibleSendQFile,
   &HylaFAXServer::listSendQ,   &HylaFAXServer::listSendQFile,
   &HylaFAXServer::nlstSendQ,   &HylaFAXServer::nlstSendQFile, },
 { "/doneq/",   false, false, false, 0,
-  HylaFAXServer::isVisibleSendQFile,
+  &HylaFAXServer::isVisibleSendQFile,
   &HylaFAXServer::listSendQ,   &HylaFAXServer::listSendQFile,
   &HylaFAXServer::nlstSendQ,   &HylaFAXServer::nlstSendQFile, },
 { "/docq/",    false,  true,  true, 0,
-  HylaFAXServer::isVisibleDocQFile,
+  &HylaFAXServer::isVisibleDocQFile,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/tmp/",     false,  true,  true, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/log/",     false, false, false, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/recvq/",   false, false,  true, 0,
-  HylaFAXServer::isVisibleRecvQFile,
+  &HylaFAXServer::isVisibleRecvQFile,
   &HylaFAXServer::listRecvQ,   &HylaFAXServer::listRecvQFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/archive/", false, false, false, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/pollq/",   false,  true,  true, 0,
-  HylaFAXServer::isVisibleRecvQFile,
+  &HylaFAXServer::isVisibleRecvQFile,
   &HylaFAXServer::listRecvQ,   &HylaFAXServer::listRecvQFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/",         false, false, false, 0,
-  HylaFAXServer::isVisibleRootFile,
+  &HylaFAXServer::isVisibleRootFile,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/etc/",      true, false, false, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/info/",    false, false, false, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/bin/",      true, false, false, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/config/",  false, false, false, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 { "/client/",   true, false, false, 0,
-  HylaFAXServer::isVisibletrue,
+  &HylaFAXServer::isVisibletrue,
   &HylaFAXServer::listDirectory,       &HylaFAXServer::listUnixFile,
   &HylaFAXServer::nlstDirectory,       &HylaFAXServer::nlstUnixFile, },
 };
@@ -409,7 +409,7 @@ HylaFAXServer::setFileOwner(const char* file)
 bool
 HylaFAXServer::fileVisible(const SpoolDir& dir, const char* filename, const struct stat& sb)
 {
-    return (IS(PRIVILEGED) || (*dir.isVisibleFile)(filename, sb));
+    return (IS(PRIVILEGED) || (this->*dir.isVisibleFile)(filename, sb));
 }
 bool
 HylaFAXServer::isVisibletrue(const char*, const struct stat&)
@@ -495,7 +495,7 @@ HylaFAXServer::listDirectory(FILE* fd, const SpoolDir& sd, DIR* dir)
        struct stat sb;
        if (!FileCache::update(path | dp->d_name, sb))
            continue;
-       if ((*sd.isVisibleFile)(dp->d_name, sb)) {
+       if ((this->*sd.isVisibleFile)(dp->d_name, sb)) {
            (this->*sd.listFile)(fd, sd, dp->d_name, sb);
            fputs("\r\n", fd);
        }
@@ -713,7 +713,7 @@ HylaFAXServer::nlstDirectory(FILE* fd, const SpoolDir& sd, DIR* dir)
        struct stat sb;
        if (!FileCache::update(path | dp->d_name, sb))
            continue;
-       if ((*sd.isVisibleFile)(dp->d_name, sb)) {
+       if ((this->*sd.isVisibleFile)(dp->d_name, sb)) {
            (this->*sd.nlstFile)(fd, sd, dp->d_name, sb);
            fputs("\r\n", fd);
        }
index 67e1cfb0a0316844263fe0981e8466e83d262cc7..7072fb0bd4b77553cf3ddb3de06c149bcd284d8f 100644 (file)
@@ -631,6 +631,7 @@ HylaFAXServer::numbertag HylaFAXServer::numbers[] = {
 { "maxloginattempts",  &HylaFAXServer::maxLoginAttempts,       5 },
 { "maxadminattempts",  &HylaFAXServer::maxAdminAttempts,       5 },
 { "maxconsecutivebadcmds",&HylaFAXServer::maxConsecutiveBadCmds,10 },
+{ "jobprotection",     &HylaFAXServer::jobProtection,          0444 },
 };
 
 void
index 157ed3f2d7ab4cb470df08635c344063fd986f68..395a9e6694e31c93ed7d6ad249f9f50bdbda01ff 100644 (file)
@@ -146,6 +146,7 @@ struct tab {                        // protocol command table entry
 };
 
 class SpoolDir;
+struct ParamProtection;
 
 struct stat;
 typedef struct tiff TIFF;
@@ -211,6 +212,7 @@ protected:
     time_t     lastTime;               // time of last shutdown notification
     time_t     discTime;               // time to disconnect service
     time_t     denyTime;               // time to deny service
+    u_int      jobProtection;          // Protection to use on Jobs
     /*
      * User authentication and login-related state.
      */
@@ -390,11 +392,11 @@ protected:
     SpoolDir* fileAccess(const char* path, int op, struct stat&);
     bool fileVisible(const SpoolDir&, const char*, const struct stat&);
 
-    static bool isVisibleRecvQFile(const char*, const struct stat&);
+    bool isVisibleRecvQFile(const char*, const struct stat&);
     void listRecvQ(FILE* fd, const SpoolDir& sd, DIR* dir);
     void listRecvQFile(FILE*, const SpoolDir&, const char*, const struct stat&);
 
-    static bool isVisibleSendQFile(const char*, const struct stat&);
+    bool isVisibleSendQFile(const char*, const struct stat&);
     void listSendQ(FILE* fd, const SpoolDir& sd, DIR* dir);
     void listSendQFile(FILE*, const SpoolDir&, const char*, const struct stat&);
     void nlstSendQ(FILE* fd, const SpoolDir& sd, DIR* dir);
@@ -404,9 +406,9 @@ protected:
     void listStatusFile(FILE*, const SpoolDir&, const char*, const struct stat&);
     void nlstStatus(FILE* fd, const SpoolDir& sd, DIR* dir);
 
-    static bool isVisibletrue(const char*, const struct stat&);
-    static bool isVisibleDocQFile(const char*, const struct stat&);
-    static bool isVisibleRootFile(const char*, const struct stat&);
+    bool isVisibletrue(const char*, const struct stat&);
+    bool isVisibleDocQFile(const char*, const struct stat&);
+    bool isVisibleRootFile(const char*, const struct stat&);
 
     void listDirectory(FILE* fd, const SpoolDir& sd, DIR* dir);
     void listUnixFile(FILE*, const SpoolDir&, const char*, const struct stat&);
@@ -603,7 +605,7 @@ struct SpoolDir {
     bool storAble;     // unprivileged clients may STOR files
     bool deleAble;     // unprivileged clients may DELE files
     ino_t ino;         // directory inode number
-    bool (*isVisibleFile)(const char*, const struct stat&);
+    bool (HylaFAXServer::*isVisibleFile)(const char*, const struct stat&);
     void (HylaFAXServer::*listDirectory)(FILE*, const SpoolDir&, DIR*);
     void (HylaFAXServer::*listFile)(FILE*, const SpoolDir&,
         const char*, const struct stat&);
index b08155d91b5ac8607a9a8fd2f25923bb4437e8e8..04b348ffdf27e6d7e33fb7b5e53d71bd925ad7d7 100644 (file)
@@ -176,17 +176,26 @@ static const struct {
 bool
 HylaFAXServer::checkAccess(const Job& job, Token t, u_int op)
 {
-    u_int n = N(params)-1;
-    u_int i = 0;
-    while (i < n && params[i].t != t)
-       i++;
-    u_int m = params[i].protect;
+    u_int m = 0;
+    if (t == T_JOB) {
+       m = jobProtection;
+    } else {
+       u_int n = N(params)-1;
+       u_int i = 0;
+       while (i < n && params[i].t != t)
+           i++;
+       m = params[i].protect;
+    }
     if (m&op)                                  // other/public access
        return (true);
     if (IS(PRIVILEGED) && ((m>>3)&op))         // administrative access
        return (true);
     if (job.owner == the_user && ((m>>6)&op))  // owner access
        return (true);
+#if 0
+    if (checkOwnerUid && ((m>>6)&op))                  // owner UID access
+       return (true);
+#endif
     return (false);
 }
 
@@ -1028,7 +1037,11 @@ HylaFAXServer::findJobOnDisk(const char* jid, fxStr& emsg)
        bool reject;
        if (req->readQFile(reject) && !reject) {
            Sys::close(req->fd), req->fd = -1;
-           return (req);
+           if (checkAccess(*req, T_JOB, A_READ) )
+               return (req);
+           emsg = "Permission denied";
+           delete req;
+           return (NULL);
        }
        emsg = "invalid or corrupted job description file";
        delete req;                     // NB: closes fd
@@ -1593,7 +1606,13 @@ HylaFAXServer::addPollOp(Job& job, const char* sep, const char* pwd)
 bool
 HylaFAXServer::isVisibleSendQFile(const char* filename, const struct stat&)
 {
-    return (filename[0] == 'q');
+    if (filename[0] == 'q') {
+       fxStr emsg;
+       Job* job = findJob(&filename[1], emsg);
+       if (job && checkAccess(*job, T_JOB, A_READ))
+           return true;
+    }
+    return false;
 }
 
 #ifdef roundup
index 4efe950cb85e0d03a0b8405086b0b91a300318e1..7429b36456f310c665fa03c8b1740c19a484d1cc 100644 (file)
@@ -405,6 +405,7 @@ FaxContact  string  \s-1\fIsee below\fP\s+1 contact address to show in help text
 FileFmt        string  \s-1\fIsee below\fP\s+1 format string for file status results
 IdleTimeout    integer \s-1900\s+1     client idle timeout in seconds
 JobFmt string  \s-1\fIsee below\fP\s+1 format string for job status results
+JobProtection  octal   \s-10444\s+1    permissions for client access to jobs
 KillTimeMap    string  \s-1\fIsee below\fP\s+1 mapping from service level to job kill time (\s-1SNPP\s+1)
 LogFacility    string  \s-1daemon\s+1  \fIsyslog\fP facility name for tracing messages
 MaxAdminAttempts       integer \s-15\s+1       maximum admin attempts before disconnecting
@@ -513,44 +514,44 @@ L Destination geographic location
 M      Notification e-mail address
 N      Desired use of private tagline (one-character symbol)
 O      Whether to use continuation cover page (one-character symbol)
-P      # pages transmitted/total # pages to transmit
+    P  # pages transmitted/total # pages to transmit
 Q      Client-specified minimum acceptable signalling rate
 R      Destination person (receiver)
-S      Sender's identity
+    S  Sender's identity
 T      Total # tries/maximum # tries
 U      Page chopping threshold (inches)
-V      Job done operation
+    V  Job done operation
 W      Communication identifier
 X      Job type (one-character symbol)
-Y      Scheduled date and time
+    Y  Scheduled date and time
 Z      Scheduled time in seconds since the UNIX epoch
 a      Job state (one-character symbol)
-b      # consecutive failed tries
-c      Client machine name
-d      Total # dials
-e      Public (external) format of dialstring
-f      # consecutive failed dials
+    b  # consecutive failed tries
+    c  Client machine name
+    d  Total # dials
+    e  Public (external) format of dialstring
+    f  # consecutive failed dials
 g      Group identifier
 h      Page chop handling (one-character symbol)
-i      Current scheduling priority
-j      Job identifier
-k      Job kill time
-l      Page length in mm
+    i  Current scheduling priority
+    j  Job identifier
+    k  Job kill time
+    l  Page length in mm
 m      Assigned modem
 n      E-mail notification handling (one-character symbol)
-o      Job owner
+    o  Job owner
 p      # pages transmitted
 q      Job retry time (MM::SS)
-r      Document resolution in lines/inch
-s      Job status information from last failure
-t      Total # tries attempted
-u      Maximum # tries
-v      Client-specified dialstring
-w      Page width in mm
-x      Maximum # dials
-y      Total # pages to transmit
-z      Time to send job
-.fi
+    r  Document resolution in lines/inch
+    s  Job status information from last failure
+    t  Total # tries attempted
+    u  Maximum # tries
+    v  Client-specified dialstring
+    w  Page width in mm
+    x  Maximum # dials
+    y  Total # pages to transmit
+    z  Time to send job
+    .fi
 .IP
 The default format string is ``%\-4j %3i %1a %6.6o %\-12.12e %5P %5D %7z %.25s''.
 This string constrains each status line to be less than 80 characters.
@@ -560,6 +561,16 @@ applications, such as
 that construct headers from the format string can constrain the width of
 column title strings.
 .TP 10
+.B JobProtection
+The permissions setting for viewing jobs in the \*(Fx queues.  The
+default setting of ``0444'' allows all users to view all jobs in the send/done
+queues.  The permissions copy unix filesystem permission, with the 3 sets
+being owner, admin, and others, instead of owner/group/other.  The only
+permissions that are meaningful are read, because write permissions are
+controlled for the specific properties of the job.  If a user doesn't have
+read permissions on the job, the job will not be visible to them.  Useful
+settings are ``0444'' (for oao=r), ``0440'' (for oa=r), and ``0400'' (for o=r).
+.TP 10
 .B KillTimeMap
 The mapping from \s-1SNPP\s+1 service level (0-11) to job expiration time
 (kill time).