/*
- * "$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).
*
}
+/*
+ * '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.
*/
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);
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;
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 */
}
}
- if (auth == AUTH_DENY)
+ if (auth == AUTH_DENY && best->satisfy == AUTH_SATISFY_ALL)
return (HTTP_FORBIDDEN);
#ifdef HAVE_LIBSSL
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...
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);
}
* 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...
/*
- * 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 $".
*/
/*
- * "$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...
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 */
*/
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);
/*
- * 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 $".
*/
/*
- * "$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.
*
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",
* 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
{
* 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
/*
- * 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 $".
*/
/*
- * "$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.
*
{
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;
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 $".
*/
/*
- * "$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).
*
{ "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 },
endpwent();
- ListenBacklog = SOMAXCONN;
+ ListenBackLog = SOMAXCONN;
LogLevel = L_ERROR;
HostNameLookups = FALSE;
Timeout = DEFAULT_TIMEOUT;
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);
/*
- * 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 $".
*/