#include "cupsd.h"
cupsd_policy_t *
cupsdAddPolicy(const char *policy)
{
cupsd_policy_t *temp,
**tempa;
if (policy == NULL)
return (NULL);
if (NumPolicies == 0)
tempa = malloc(sizeof(cupsd_policy_t *));
else
tempa = realloc(Policies, sizeof(cupsd_policy_t *) * (NumPolicies + 1));
if (tempa == NULL)
return (NULL);
Policies = tempa;
tempa += NumPolicies;
if ((temp = calloc(1, sizeof(cupsd_policy_t))) != NULL)
{
temp->name = strdup(policy);
*tempa = temp;
NumPolicies ++;
}
return (temp);
}
cupsd_location_t *
cupsdAddPolicyOp(cupsd_policy_t *p,
cupsd_location_t *po,
ipp_op_t op)
{
int i;
cupsd_location_t *temp,
**tempa;
char name[1024];
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddPolicyOp(p=%p, po=%p, op=%x(%s))",
p, po, op, ippOpString(op));
if (p == NULL)
return (NULL);
if (p->num_ops == 0)
tempa = malloc(sizeof(cupsd_location_t *));
else
tempa = realloc(p->ops, sizeof(cupsd_location_t *) * (p->num_ops + 1));
if (tempa == NULL)
return (NULL);
p->ops = tempa;
if ((temp = calloc(1, sizeof(cupsd_location_t))) != NULL)
{
p->ops = tempa;
tempa[p->num_ops] = temp;
p->num_ops ++;
temp->op = op;
temp->limit = CUPSD_AUTH_LIMIT_IPP;
if (po)
{
temp->order_type = po->order_type;
temp->type = po->type;
temp->level = po->level;
temp->satisfy = po->satisfy;
temp->encryption = po->encryption;
for (i = 0; i < po->num_names; i ++)
cupsdAddName(temp, po->names[i]);
for (i = 0; i < po->num_allow; i ++)
switch (po->allow[i].type)
{
case CUPSD_AUTH_IP :
cupsdAllowIP(temp, po->allow[i].mask.ip.address,
po->allow[i].mask.ip.netmask);
break;
case CUPSD_AUTH_INTERFACE :
snprintf(name, sizeof(name), "@IF(%s)",
po->allow[i].mask.name.name);
cupsdAllowHost(temp, name);
break;
default :
cupsdAllowHost(temp, po->allow[i].mask.name.name);
break;
}
for (i = 0; i < po->num_deny; i ++)
switch (po->deny[i].type)
{
case CUPSD_AUTH_IP :
cupsdDenyIP(temp, po->deny[i].mask.ip.address,
po->deny[i].mask.ip.netmask);
break;
case CUPSD_AUTH_INTERFACE :
snprintf(name, sizeof(name), "@IF(%s)",
po->deny[i].mask.name.name);
cupsdDenyHost(temp, name);
break;
default :
cupsdDenyHost(temp, po->deny[i].mask.name.name);
break;
}
}
}
return (temp);
}
http_status_t
cupsdCheckPolicy(cupsd_policy_t *p,
cupsd_client_t *con,
const char *owner)
{
cupsd_location_t *po;
if (!p || !con)
{
cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p!", p, con);
return ((http_status_t)0);
}
if ((po = cupsdFindPolicyOp(p, con->request->request.op.operation_id)) == NULL)
{
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckPolicy: No matching operation, returning 0!");
return ((http_status_t)0);
}
con->best = po;
return (cupsdIsAuthorized(con, owner));
}
void
cupsdDeleteAllPolicies(void)
{
int i, j;
cupsd_policy_t **p;
cupsd_location_t **po;
if (NumPolicies == 0)
return;
for (i = NumPolicies, p = Policies; i > 0; i --, p ++)
{
for (j = (*p)->num_ops, po = (*p)->ops; j > 0; j --, po ++)
cupsdDeleteLocation(*po);
if ((*p)->num_ops > 0)
free((*p)->ops);
free(*p);
}
free(Policies);
NumPolicies = 0;
Policies = NULL;
}
cupsd_policy_t *
cupsdFindPolicy(const char *policy)
{
int i;
cupsd_policy_t **p;
if (policy == NULL)
return (NULL);
for (i = NumPolicies, p = Policies; i > 0; i --, p ++)
if (!strcasecmp(policy, (*p)->name))
return (*p);
return (NULL);
}
cupsd_location_t *
cupsdFindPolicyOp(cupsd_policy_t *p,
ipp_op_t op)
{
int i;
cupsd_location_t **po;
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))\n",
p, op, ippOpString(op));
if (p == NULL)
return (NULL);
for (i = p->num_ops, po = p->ops; i > 0; i --, po ++)
if ((*po)->op == op)
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cupsdFindPolicyOp: Found exact match...");
return (*po);
}
for (i = p->num_ops, po = p->ops; i > 0; i --, po ++)
if ((*po)->op == IPP_ANY_OPERATION)
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cupsdFindPolicyOp: Found wildcard match...");
return (*po);
}
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found!");
return (NULL);
}