/* * "$Id: policy.c 7673 2008-06-18 22:31:26Z mike $" * * Policy routines for the Common UNIX Printing System (CUPS). * * Copyright 2007-2008 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright * law. Distribution and use rights are outlined in the file "LICENSE.txt" * which should have been included with this file. If this file is * file is missing or damaged, see the license at "http://www.cups.org/". * * Contents: * * cupsdAddPolicy() - Add a policy to the system. * cupsdAddPolicyOp() - Add an operation to a policy. * cupsdCheckPolicy() - Check the IPP operation and username against * a policy. * cupsdDeleteAllPolicies() - Delete all policies in memory. * cupsdFindPolicy() - Find a named policy. * cupsdFindPolicyOp() - Find a policy operation. */ /* * Include necessary headers... */ #include "cupsd.h" /* * Local functions... */ static int compare_ops(cupsd_location_t *a, cupsd_location_t *b); static int compare_policies(cupsd_policy_t *a, cupsd_policy_t *b); static int hash_op(cupsd_location_t *op); /* * 'AddPolicy()' - Add a policy to the system. */ cupsd_policy_t * /* O - Policy */ cupsdAddPolicy(const char *policy) /* I - Name of policy */ { cupsd_policy_t *temp; /* Pointer to policy */ if (!policy) return (NULL); if (!Policies) Policies = cupsArrayNew((cups_array_func_t)compare_policies, NULL); if (!Policies) return (NULL); if ((temp = calloc(1, sizeof(cupsd_policy_t))) != NULL) { cupsdSetString(&temp->name, policy); cupsArrayAdd(Policies, temp); } return (temp); } /* * 'cupsdAddPolicyOp()' - Add an operation to a policy. */ cupsd_location_t * /* O - New policy operation */ cupsdAddPolicyOp(cupsd_policy_t *p, /* I - Policy */ cupsd_location_t *po, /* I - Policy operation to copy */ ipp_op_t op) /* I - IPP operation code */ { int i; /* Looping var */ cupsd_location_t *temp; /* New policy operation */ char name[1024]; /* Interface name */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddPolicyOp(p=%p, po=%p, op=%x(%s))", p, po, op, ippOpString(op)); if (!p) return (NULL); if (!p->ops) p->ops = cupsArrayNew2((cups_array_func_t)compare_ops, NULL, (cups_ahash_func_t)hash_op, 128); if (!p->ops) return (NULL); if ((temp = calloc(1, sizeof(cupsd_location_t))) != NULL) { temp->op = op; temp->limit = CUPSD_AUTH_LIMIT_IPP; cupsArrayAdd(p->ops, temp); if (po) { /* * Copy the specified policy to the new one... */ 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); } /* * 'cupsdCheckPolicy()' - Check the IPP operation and username against a policy. */ http_status_t /* I - 1 if OK, 0 otherwise */ cupsdCheckPolicy(cupsd_policy_t *p, /* I - Policy */ cupsd_client_t *con, /* I - Client connection */ const char *owner) /* I - Owner of object */ { cupsd_location_t *po; /* Current policy operation */ /* * Range check... */ if (!p || !con) { cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p!", p, con); return ((http_status_t)0); } /* * Find a match for the operation... */ 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 the status of the check... */ return (cupsdIsAuthorized(con, owner)); } /* * 'cupsdDeleteAllPolicies()' - Delete all policies in memory. */ void cupsdDeleteAllPolicies(void) { cupsd_policy_t *p; /* Current policy */ cupsd_location_t *po; /* Current policy op */ if (!Policies) return; for (p = (cupsd_policy_t *)cupsArrayFirst(Policies); p; p = (cupsd_policy_t *)cupsArrayNext(Policies)) { for (po = (cupsd_location_t *)cupsArrayFirst(p->ops); po; po = (cupsd_location_t *)cupsArrayNext(p->ops)) cupsdDeleteLocation(po); cupsArrayDelete(p->ops); cupsdClearString(&p->name); free(p); } cupsArrayDelete(Policies); Policies = NULL; } /* * 'cupsdFindPolicy()' - Find a named policy. */ cupsd_policy_t * /* O - Policy */ cupsdFindPolicy(const char *policy) /* I - Name of policy */ { cupsd_policy_t key; /* Search key */ /* * Range check... */ if (!policy) return (NULL); /* * Look it up... */ key.name = (char *)policy; return ((cupsd_policy_t *)cupsArrayFind(Policies, &key)); } /* * 'cupsdFindPolicyOp()' - Find a policy operation. */ cupsd_location_t * /* O - Policy operation */ cupsdFindPolicyOp(cupsd_policy_t *p, /* I - Policy */ ipp_op_t op) /* I - IPP operation */ { cupsd_location_t key, /* Search key... */ *po; /* Current policy operation */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))", p, op, ippOpString(op)); /* * Range check... */ if (!p) return (NULL); /* * Check the operation against the available policies... */ key.op = op; if ((po = (cupsd_location_t *)cupsArrayFind(p->ops, &key)) != NULL) { cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: Found exact match..."); return (po); } key.op = IPP_ANY_OPERATION; if ((po = (cupsd_location_t *)cupsArrayFind(p->ops, &key)) != NULL) { cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: Found wildcard match..."); return (po); } cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found!"); return (NULL); } /* * 'compare_ops()' - Compare two operations. */ static int /* O - Result of comparison */ compare_ops(cupsd_location_t *a, /* I - First operation */ cupsd_location_t *b) /* I - Second operation */ { return (a->op - b->op); } /* * 'compare_policies()' - Compare two policies. */ static int /* O - Result of comparison */ compare_policies(cupsd_policy_t *a, /* I - First policy */ cupsd_policy_t *b) /* I - Second policy */ { return (strcasecmp(a->name, b->name)); } /* * 'hash_op()' - Generate a lookup hash for the operation. */ static int /* O - Hash value */ hash_op(cupsd_location_t *op) /* I - Operation */ { return (((op->op >> 6) & 0x40) | (op->op & 0x3f)); } /* * End of "$Id: policy.c 7673 2008-06-18 22:31:26Z mike $". */