]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Added code to support Satisfy, Limit, multiple users, and multiple groups
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Tue, 20 Feb 2001 22:41:55 +0000 (22:41 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Tue, 20 Feb 2001 22:41:55 +0000 (22:41 +0000)
in authentication/access control code.

New interfaces added to conf*.c.

Fixup some of the double lookup code in AcceptClient()...

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@1579 7a7537e8-13f0-0310-91df-b6672ffda945

scheduler/auth.c
scheduler/auth.h
scheduler/client.c
scheduler/client.h
scheduler/conf.c

index 72572dd893031fa43c15e0552e5df40be39ecf8e..4560b995397782ba6dc1270d3c23da38562c2dc6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: auth.c,v 1.39 2001/01/22 15:03:57 mike Exp $"
+ * "$Id: auth.c,v 1.40 2001/02/20 22:41:54 mike Exp $"
  *
  *   Authorization routines for the Common UNIX Printing System (CUPS).
  *
@@ -119,6 +119,42 @@ AddLocation(const char *location)  /* I - Location path */
 }
 
 
+/*
+ * 'AddName()' - Add a name to a location...
+ */
+
+void
+AddName(location_t *loc,       /* I - Location to add to */
+        char       *name)      /* I - Name to add */
+{
+  char **temp;                 /* Pointer to names array */
+
+
+  if (loc->num_names == 0)
+    temp = malloc(sizeof(char *));
+  else
+    temp = realloc(loc->names, (loc->num_names + 1) * sizeof(char *));
+
+  if (temp == NULL)
+  {
+    LogMessage(L_ERROR, "Unable to add name to location %s: %s", loc->location,
+               strerror(errno));
+    return;
+  }
+
+  loc->names = temp;
+
+  if ((temp[loc->num_names] = strdup(name)) == NULL)
+  {
+    LogMessage(L_ERROR, "Unable to duplicate name for location %s: %s",
+               loc->location, strerror(errno));
+    return;
+  }
+
+  loc->num_names ++;
+}
+
+
 /*
  * 'AllowHost()' - Add a host name that is allowed to access the location.
  */
@@ -236,6 +272,12 @@ DeleteAllLocations(void)
 
   for (i = NumLocations, loc = Locations; i > 0; i --, loc ++)
   {
+    for (j = loc->num_names - 1; j >= 0; j --)
+      free(loc->names[j]);
+
+    if (loc->num_names > 0)
+      free(loc->names);
+
     for (j = loc->num_allow, mask = loc->allow; j > 0; j --, mask ++)
       if (mask->type == AUTH_NAME)
         free(mask->mask.name.name);
@@ -321,19 +363,39 @@ FindBest(client_t *con)           /* I - Connection */
   location_t   *loc,           /* Current location */
                *best;          /* Best match for location so far */
   int          bestlen;        /* Length of best match */
+  int          limit;          /* Limit field */
+  static int   limits[] =      /* Map http_status_t to AUTH_LIMIT_xyz */
+               {
+                 AUTH_LIMIT_ALL,
+                 AUTH_LIMIT_OPTIONS,
+                 AUTH_LIMIT_GET,
+                 AUTH_LIMIT_GET,
+                 AUTH_LIMIT_HEAD,
+                 AUTH_LIMIT_POST,
+                 AUTH_LIMIT_POST,
+                 AUTH_LIMIT_POST,
+                 AUTH_LIMIT_PUT,
+                 AUTH_LIMIT_PUT,
+                 AUTH_LIMIT_DELETE,
+                 AUTH_LIMIT_TRACE,
+                 AUTH_LIMIT_ALL,
+                 AUTH_LIMIT_ALL
+               };
 
 
  /*
   * Loop through the list of locations to find a match...
   */
 
+  limit   = limits[con->http.status];
   best    = NULL;
   bestlen = 0;
 
   for (i = NumLocations, loc = Locations; i > 0; i --, loc ++)
     if (loc->length > bestlen &&
         strncmp(con->uri, loc->location, loc->length) == 0 &&
-       loc->location[0] == '/')
+       loc->location[0] == '/' &&
+       (limit & loc->limit) != 0)
     {
       best    = loc;
       bestlen = loc->length;
@@ -376,7 +438,7 @@ FindLocation(const char *location)  /* I - Connection */
 http_status_t                  /* O - HTTP_OK if authorized or error code */
 IsAuthorized(client_t *con)    /* I - Connection */
 {
-  int          i,              /* Looping var */
+  int          i, j,           /* Looping vars */
                auth;           /* Authorization status */
   unsigned     address;        /* Authorization address */
   location_t   *best;          /* Best match for location so far */
@@ -476,7 +538,7 @@ IsAuthorized(client_t *con) /* I - Connection */
     }
   }
 
-  if (auth == AUTH_DENY)
+  if (auth == AUTH_DENY && best->satisfy == AUTH_SATISFY_ALL)
     return (HTTP_FORBIDDEN);
 
 #ifdef HAVE_LIBSSL
@@ -499,7 +561,12 @@ IsAuthorized(client_t *con)        /* I - Connection */
                con->username, con->password));
 
   if (con->username[0] == '\0')
-    return (HTTP_UNAUTHORIZED);                /* Non-anonymous needs user/pass */
+  {
+    if (best->satisfy == AUTH_SATISFY_ALL || auth == AUTH_DENY)
+      return (HTTP_UNAUTHORIZED);      /* Non-anonymous needs user/pass */
+    else
+      return (HTTP_OK);                        /* unless overridden with Satisfy */
+  }
 
  /*
   * Check the user's password...
@@ -653,10 +720,10 @@ IsAuthorized(client_t *con)       /* I - Connection */
         return (HTTP_UNAUTHORIZED);
       }
 
-      if (!get_md5_passwd(con->username, best->group_name, md5))
+      if (!get_md5_passwd(con->username, best->names[0], md5))
       {
-        LogMessage(L_ERROR, "IsAuthorized: No user:group of \"%s:%s\" in passwd.md5!",
-                  con->username, best->group_name);
+        LogMessage(L_ERROR, "IsAuthorized: No user:group for \"%s:%s\" in passwd.md5!",
+                  con->username, best->names[0]);
         return (HTTP_UNAUTHORIZED);
       }
 
@@ -676,33 +743,58 @@ IsAuthorized(client_t *con)       /* I - Connection */
   * access... (root always matches)
   */
 
-  if (best->level == AUTH_USER || strcmp(con->username, "root") == 0)
+  if (strcmp(con->username, "root") == 0)
     return (HTTP_OK);
 
- /*
-  * Check to see if this user is in the specified group...
-  */
-
-  grp = getgrnam(best->group_name);
-  endgrent();
-
-  if (grp == NULL)                     /* No group by that name??? */
+  if (best->level == AUTH_USER)
   {
-    LogMessage(L_WARN, "IsAuthorized: group name \"%s\" does not exist!",
-               best->group_name);
-    return (HTTP_FORBIDDEN);
-  }
+   /*
+    * If there are no names associated with this location, then
+    * any valid user is OK...
+    */
 
-  for (i = 0; grp->gr_mem[i] != NULL; i ++)
-    if (strcmp(con->username, grp->gr_mem[i]) == 0)
+    if (best->num_names == 0)
       return (HTTP_OK);
 
+   /*
+    * Otherwise check the user list and return OK if this user is
+    * allowed...
+    */
+
+    for (i = 0; i < best->num_names; i ++)
+      if (strcmp(con->username, best->names[i]) == 0)
+        return (HTTP_OK);
+
+    return (HTTP_UNAUTHORIZED);
+  }
+
  /*
-  * Check to see if the default group ID matches for the user...
+  * Check to see if this user is in any of the named groups...
   */
 
-  if (grp->gr_gid == pw->pw_gid)
-    return (HTTP_OK);
+  for (i = 0; i < best->num_names; i ++)
+  {
+    grp = getgrnam(best->names[i]);
+    endgrent();
+
+    if (grp == NULL)                   /* No group by that name??? */
+    {
+      LogMessage(L_WARN, "IsAuthorized: group name \"%s\" does not exist!",
+                best->names[i]);
+      return (HTTP_FORBIDDEN);
+    }
+
+    for (j = 0; grp->gr_mem[j] != NULL; j ++)
+      if (strcmp(con->username, grp->gr_mem[j]) == 0)
+       return (HTTP_OK);
+
+   /*
+    * Check to see if the default group ID matches for the user...
+    */
+
+    if (grp->gr_gid == pw->pw_gid)
+      return (HTTP_OK);
+  }
 
  /*
   * The user isn't part of the specified group, so deny access...
@@ -909,5 +1001,5 @@ pam_func(int                      num_msg, /* I - Number of messages */
 
 
 /*
- * End of "$Id: auth.c,v 1.39 2001/01/22 15:03:57 mike Exp $".
+ * End of "$Id: auth.c,v 1.40 2001/02/20 22:41:54 mike Exp $".
  */
index dad529a2d403ee5071fe3e20b3fdce3d6659ccf0..3cbae69ce51d015bd49a586dbef48b35ec88b34a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: auth.h,v 1.14 2001/01/22 15:03:58 mike Exp $"
+ * "$Id: auth.h,v 1.15 2001/02/20 22:41:55 mike Exp $"
  *
  *   Authorization definitions for the Common UNIX Printing System (CUPS)
  *   scheduler.
 #define AUTH_NAME              0       /* Authorize host by name */
 #define AUTH_IP                        1       /* Authorize host by IP */
 
+#define AUTH_SATISFY_ANY       1       /* Satisfy either address or auth */
+#define AUTH_SATISFY_ALL       2       /* Satisfy both address and auth */
+
+#define AUTH_LIMIT_DELETE      1       /* Limit DELETE requests */
+#define AUTH_LIMIT_GET         2       /* Limit GET requests */
+#define AUTH_LIMIT_HEAD                4       /* Limit HEAD requests */
+#define AUTH_LIMIT_OPTIONS     8       /* Limit OPTIONS requests */
+#define AUTH_LIMIT_POST                16      /* Limit POST requests */
+#define AUTH_LIMIT_PUT         32      /* Limit PUT requests */
+#define AUTH_LIMIT_TRACE       64      /* Limit TRACE requests */
+#define AUTH_LIMIT_ALL         127     /* Limit all requests */
+
 
 /*
  * HTTP access control structures...
@@ -71,11 +83,14 @@ typedef struct
 typedef struct
 {
   char         location[HTTP_MAX_URI]; /* Location of resource */
-  int          length,                 /* Length of location string */
+  int          limit,                  /* Limit for these types of requests */
+               length,                 /* Length of location string */
                order_type,             /* Allow or Deny */
                type,                   /* Type of authentication */
-               level;                  /* Access level required */
-  char         group_name[MAX_USERPASS];/* User group name */
+               level,                  /* Access level required */
+               satisfy;                /* Satisfy any or all limits? */
+  int          num_names;              /* Number of names */
+  char         **names;                /* User or group names */
   int          num_allow;              /* Number of Allow lines */
   authmask_t   *allow;                 /* Allow lines */
   int          num_deny;               /* Number of Deny lines */
@@ -99,6 +114,7 @@ VAR location_t               *Locations      VALUE(NULL);
  */
 
 extern location_t      *AddLocation(const char *location);
+extern void            AddName(location_t *loc, char *name);
 extern void            AllowHost(location_t *loc, char *name);
 extern void            AllowIP(location_t *loc, unsigned address,
                                unsigned netmask);
@@ -114,5 +130,5 @@ extern http_status_t        IsAuthorized(client_t *con);
 
 
 /*
- * End of "$Id: auth.h,v 1.14 2001/01/22 15:03:58 mike Exp $".
+ * End of "$Id: auth.h,v 1.15 2001/02/20 22:41:55 mike Exp $".
  */
index 4805cf8cb2d0553c330fccebcfe576ea8e5f149f..8f70ce108f76bd33c3aa2eea894ea8f61a32b538 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: client.c,v 1.84 2001/02/20 22:02:11 mike Exp $"
+ * "$Id: client.c,v 1.85 2001/02/20 22:41:55 mike Exp $"
  *
  *   Client routines for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -74,7 +74,6 @@ AcceptClient(listener_t *lis) /* I - Listener socket */
   client_t             *con;   /* New client pointer */
   unsigned             address;/* Address of client */
   struct hostent       *host;  /* Host entry for address */
-                       *ip;    /* Host entry for name */
 
 
   LogMessage(L_DEBUG2, "AcceptClient(%08x) %d NumClients = %d",
@@ -168,19 +167,19 @@ AcceptClient(listener_t *lis)     /* I - Listener socket */
     * Do double lookups as needed...
     */
 
-    if ((ip = gethostbyname(con->http.hostname)) != NULL)
+    if ((host = gethostbyname(con->http.hostname)) != NULL)
     {
      /*
       * See if the hostname maps to the IP address...
       */
 
-      if (ip->h_length != 4 || ip->h_addrtype != AF_INET)
+      if (host->h_length != 4 || host->h_addrtype != AF_INET)
       {
        /*
         * Not an IPv4 address...
        */
 
-       ip = NULL;
+       host = NULL;
       }
       else
       {
@@ -188,16 +187,16 @@ AcceptClient(listener_t *lis)     /* I - Listener socket */
         * Compare all of the addresses against this one...
        */
 
-       for (i = 0; ip->h_addr_list[i]; i ++)
-          if (memcmp(&(con->http.hostaddr.sin_addr), ip->h_addr_list[i], 4) == 0)
+       for (i = 0; host->h_addr_list[i]; i ++)
+          if (memcmp(&(con->http.hostaddr.sin_addr), host->h_addr_list[i], 4) == 0)
            break;
 
-        if (!ip->h_addr_list[i])
-         ip = NULL;
+        if (!host->h_addr_list[i])
+         host = NULL;
       }
     }
 
-    if (ip == NULL)
+    if (host == NULL)
     {
      /*
       * Can't have a hostname that doesn't resolve to the same IP address
@@ -2079,5 +2078,5 @@ pipe_command(client_t *con,       /* I - Client connection */
 
 
 /*
- * End of "$Id: client.c,v 1.84 2001/02/20 22:02:11 mike Exp $".
+ * End of "$Id: client.c,v 1.85 2001/02/20 22:41:55 mike Exp $".
  */
index ed432398573d9ebc6f69f910b86b0b9f68c35a62..325620ca5997842549d532958ddb30ebf461bd4c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: client.h,v 1.16 2001/02/20 22:02:11 mike Exp $"
+ * "$Id: client.h,v 1.17 2001/02/20 22:41:55 mike Exp $"
  *
  *   Client definitions for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -58,6 +58,7 @@ typedef struct
 {
   int                  fd;             /* File descriptor for this server */
   struct sockaddr_in   address;        /* Bind address of socket */
+  http_encryption_t    encryption;     /* To encrypt or not to encrypt... */
 } listener_t;
 
 
@@ -99,5 +100,5 @@ extern void  StopListening(void);
 extern int     WriteClient(client_t *con);
 
 /*
- * End of "$Id: client.h,v 1.16 2001/02/20 22:02:11 mike Exp $".
+ * End of "$Id: client.h,v 1.17 2001/02/20 22:41:55 mike Exp $".
  */
index 4c4b31c6fec17bd712f3a0ae3639b08b044e0276..4873e212457bcbd241b83cae4fdb8fad4cc46311 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: conf.c,v 1.70 2001/02/20 22:02:11 mike Exp $"
+ * "$Id: conf.c,v 1.71 2001/02/20 22:41:55 mike Exp $"
  *
  *   Configuration routines for the Common UNIX Printing System (CUPS).
  *
@@ -116,6 +116,7 @@ static var_t        variables[] =
   { "MaxClients",      &MaxClients,            VAR_INTEGER,    0 },
   { "MaxLogSize",      &MaxLogSize,            VAR_INTEGER,    0 },
   { "MaxRequestSize",  &MaxRequestSize,        VAR_INTEGER,    0 },
+  { "LimitRequestBody",        &MaxRequestSize,        VAR_INTEGER,    0 },
   { "PreserveJobHistory", &JobHistory,         VAR_BOOLEAN,    0 },
   { "PreserveJobFiles",        &JobFiles,              VAR_BOOLEAN,    0 },
   { "MaxJobs",         &MaxJobs,               VAR_INTEGER,    0 },
@@ -307,7 +308,7 @@ ReadConfiguration(void)
 
   endpwent();
 
-  ListenBacklog    = SOMAXCONN;
+  ListenBackLog    = SOMAXCONN;
   LogLevel         = L_ERROR;
   HostNameLookups  = FALSE;
   Timeout          = DEFAULT_TIMEOUT;
@@ -1387,14 +1388,14 @@ read_location(FILE *fp,         /* I - Configuration file */
       else if (strcasecmp(value, "system") == 0)
       {
         loc->level = AUTH_GROUP;
-       strncpy(loc->group_name, SystemGroup, sizeof(loc->group_name) - 1);
+       AddName(loc, SystemGroup);
       }
       else
         LogMessage(L_WARN, "Unknown authorization class %s on line %d.",
                   value, linenum);
     }
     else if (strcmp(name, "AuthGroupName") == 0)
-      strncpy(loc->group_name, value, sizeof(loc->group_name) - 1);
+      AddName(loc, value);
     else
       LogMessage(L_ERROR, "Unknown Location directive %s on line %d.",
                 name, linenum);
@@ -1500,5 +1501,5 @@ get_address(char               *value,            /* I - Value string */
 
 
 /*
- * End of "$Id: conf.c,v 1.70 2001/02/20 22:02:11 mike Exp $".
+ * End of "$Id: conf.c,v 1.71 2001/02/20 22:41:55 mike Exp $".
  */