]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/policy.c
Add cupsArrayNew3 API which offers memory management for array elements.
[thirdparty/cups.git] / scheduler / policy.c
CommitLineData
f27bd5ab 1/*
c9d3f842 2 * "$Id$"
f27bd5ab 3 *
4 * Policy routines for the Common UNIX Printing System (CUPS).
5 *
7ed0bc61 6 * Copyright 2007-2008 by Apple Inc.
dfd3d12a 7 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
f27bd5ab 8 *
9 * These coded instructions, statements, and computer programs are the
4e8d321f 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
f27bd5ab 14 *
15 * Contents:
16 *
99baf768 17 * cupsdAddPolicy() - Add a policy to the system.
18 * cupsdAddPolicyOp() - Add an operation to a policy.
19 * cupsdCheckPolicy() - Check the IPP operation and username against
20 * a policy.
21 * cupsdDeleteAllPolicies() - Delete all policies in memory.
22 * cupsdFindPolicy() - Find a named policy.
23 * cupsdFindPolicyOp() - Find a policy operation.
f27bd5ab 24 */
25
26/*
27 * Include necessary headers...
28 */
29
30#include "cupsd.h"
53ca8055 31
f27bd5ab 32
71d7e94c 33/*
34 * Local functions...
35 */
36
37static int compare_ops(cupsd_location_t *a, cupsd_location_t *b);
38static int compare_policies(cupsd_policy_t *a, cupsd_policy_t *b);
39static int hash_op(cupsd_location_t *op);
40
41
f27bd5ab 42/*
43 * 'AddPolicy()' - Add a policy to the system.
44 */
45
99baf768 46cupsd_policy_t * /* O - Policy */
47cupsdAddPolicy(const char *policy) /* I - Name of policy */
f27bd5ab 48{
71d7e94c 49 cupsd_policy_t *temp; /* Pointer to policy */
53ca8055 50
51
71d7e94c 52 if (!policy)
53ca8055 53 return (NULL);
54
71d7e94c 55 if (!Policies)
56 Policies = cupsArrayNew((cups_array_func_t)compare_policies, NULL);
53ca8055 57
71d7e94c 58 if (!Policies)
4b6bdd9f 59 return (NULL);
60
99baf768 61 if ((temp = calloc(1, sizeof(cupsd_policy_t))) != NULL)
53ca8055 62 {
71d7e94c 63 cupsdSetString(&temp->name, policy);
64 cupsArrayAdd(Policies, temp);
53ca8055 65 }
66
67 return (temp);
f27bd5ab 68}
69
70
71/*
99baf768 72 * 'cupsdAddPolicyOp()' - Add an operation to a policy.
f27bd5ab 73 */
74
f3e786fc 75cupsd_location_t * /* O - New policy operation */
76cupsdAddPolicyOp(cupsd_policy_t *p, /* I - Policy */
77 cupsd_location_t *po, /* I - Policy operation to copy */
78 ipp_op_t op) /* I - IPP operation code */
f27bd5ab 79{
f3e786fc 80 int i; /* Looping var */
71d7e94c 81 cupsd_location_t *temp; /* New policy operation */
f3e786fc 82 char name[1024]; /* Interface name */
53ca8055 83
84
f3e786fc 85 cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddPolicyOp(p=%p, po=%p, op=%x(%s))",
86 p, po, op, ippOpString(op));
0051f336 87
71d7e94c 88 if (!p)
53ca8055 89 return (NULL);
90
71d7e94c 91 if (!p->ops)
92 p->ops = cupsArrayNew2((cups_array_func_t)compare_ops, NULL,
93 (cups_ahash_func_t)hash_op, 128);
53ca8055 94
71d7e94c 95 if (!p->ops)
4b6bdd9f 96 return (NULL);
97
589eb420 98 if ((temp = calloc(1, sizeof(cupsd_location_t))) != NULL)
53ca8055 99 {
99baf768 100 temp->op = op;
7ed0bc61 101 temp->limit = CUPSD_AUTH_LIMIT_IPP;
4b6bdd9f 102
71d7e94c 103 cupsArrayAdd(p->ops, temp);
104
4b6bdd9f 105 if (po)
106 {
107 /*
108 * Copy the specified policy to the new one...
109 */
110
99baf768 111 temp->order_type = po->order_type;
0051f336 112 temp->type = po->type;
99baf768 113 temp->level = po->level;
114 temp->satisfy = po->satisfy;
115 temp->encryption = po->encryption;
116
4b6bdd9f 117 for (i = 0; i < po->num_names; i ++)
589eb420 118 cupsdAddName(temp, po->names[i]);
99baf768 119
120 for (i = 0; i < po->num_allow; i ++)
121 switch (po->allow[i].type)
122 {
7ed0bc61 123 case CUPSD_AUTH_IP :
589eb420 124 cupsdAllowIP(temp, po->allow[i].mask.ip.address,
71d7e94c 125 po->allow[i].mask.ip.netmask);
99baf768 126 break;
127
7ed0bc61 128 case CUPSD_AUTH_INTERFACE :
99baf768 129 snprintf(name, sizeof(name), "@IF(%s)",
130 po->allow[i].mask.name.name);
589eb420 131 cupsdAllowHost(temp, name);
99baf768 132 break;
133
134 default :
589eb420 135 cupsdAllowHost(temp, po->allow[i].mask.name.name);
99baf768 136 break;
137 }
138
139 for (i = 0; i < po->num_deny; i ++)
140 switch (po->deny[i].type)
141 {
7ed0bc61 142 case CUPSD_AUTH_IP :
589eb420 143 cupsdDenyIP(temp, po->deny[i].mask.ip.address,
71d7e94c 144 po->deny[i].mask.ip.netmask);
99baf768 145 break;
146
7ed0bc61 147 case CUPSD_AUTH_INTERFACE :
99baf768 148 snprintf(name, sizeof(name), "@IF(%s)",
149 po->deny[i].mask.name.name);
589eb420 150 cupsdDenyHost(temp, name);
99baf768 151 break;
152
153 default :
589eb420 154 cupsdDenyHost(temp, po->deny[i].mask.name.name);
99baf768 155 break;
156 }
4b6bdd9f 157 }
53ca8055 158 }
159
160 return (temp);
f27bd5ab 161}
162
163
164/*
99baf768 165 * 'cupsdCheckPolicy()' - Check the IPP operation and username against a policy.
f27bd5ab 166 */
167
5df46530 168http_status_t /* I - 1 if OK, 0 otherwise */
99baf768 169cupsdCheckPolicy(cupsd_policy_t *p, /* I - Policy */
f3e786fc 170 cupsd_client_t *con, /* I - Client connection */
99baf768 171 const char *owner) /* I - Owner of object */
f27bd5ab 172{
f3e786fc 173 cupsd_location_t *po; /* Current policy operation */
53ca8055 174
175
176 /*
177 * Range check...
178 */
179
bd5510a5 180 if (!p || !con)
fd09381d 181 {
f3e786fc 182 cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p!", p, con);
fd09381d 183
be5262d8 184 return ((http_status_t)0);
fd09381d 185 }
53ca8055 186
187 /*
4b6bdd9f 188 * Find a match for the operation...
53ca8055 189 */
190
0051f336 191 if ((po = cupsdFindPolicyOp(p, con->request->request.op.operation_id)) == NULL)
5934328c 192 {
f3e786fc 193 cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckPolicy: No matching operation, returning 0!");
be5262d8 194 return ((http_status_t)0);
5934328c 195 }
4b6bdd9f 196
f32b1ead 197 con->best = po;
53ca8055 198
199 /*
4b6bdd9f 200 * Return the status of the check...
53ca8055 201 */
202
5df46530 203 return (cupsdIsAuthorized(con, owner));
f27bd5ab 204}
205
206
207/*
99baf768 208 * 'cupsdDeleteAllPolicies()' - Delete all policies in memory.
f27bd5ab 209 */
210
211void
99baf768 212cupsdDeleteAllPolicies(void)
f27bd5ab 213{
71d7e94c 214 cupsd_policy_t *p; /* Current policy */
215 cupsd_location_t *po; /* Current policy op */
715a3e88 216 cupsd_printer_t *printer; /* Current printer */
53ca8055 217
218
71d7e94c 219 if (!Policies)
53ca8055 220 return;
221
715a3e88 222 /*
223 * First clear the policy pointers for all printers...
224 */
225
226 for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
227 printer;
228 printer = (cupsd_printer_t *)cupsArrayNext(Printers))
229 printer->op_policy_ptr = NULL;
230
231 /*
232 * Then free all of the policies...
233 */
234
71d7e94c 235 for (p = (cupsd_policy_t *)cupsArrayFirst(Policies);
236 p;
237 p = (cupsd_policy_t *)cupsArrayNext(Policies))
53ca8055 238 {
71d7e94c 239 for (po = (cupsd_location_t *)cupsArrayFirst(p->ops);
240 po;
241 po = (cupsd_location_t *)cupsArrayNext(p->ops))
242 cupsdDeleteLocation(po);
243
244 cupsArrayDelete(p->ops);
245 cupsdClearString(&p->name);
246 free(p);
53ca8055 247 }
248
71d7e94c 249 cupsArrayDelete(Policies);
53ca8055 250
71d7e94c 251 Policies = NULL;
f27bd5ab 252}
253
254
255/*
99baf768 256 * 'cupsdFindPolicy()' - Find a named policy.
f27bd5ab 257 */
258
99baf768 259cupsd_policy_t * /* O - Policy */
260cupsdFindPolicy(const char *policy) /* I - Name of policy */
f27bd5ab 261{
71d7e94c 262 cupsd_policy_t key; /* Search key */
53ca8055 263
264
265 /*
266 * Range check...
267 */
268
71d7e94c 269 if (!policy)
53ca8055 270 return (NULL);
271
272 /*
71d7e94c 273 * Look it up...
53ca8055 274 */
275
71d7e94c 276 key.name = (char *)policy;
277 return ((cupsd_policy_t *)cupsArrayFind(Policies, &key));
f27bd5ab 278}
279
280
281/*
99baf768 282 * 'cupsdFindPolicyOp()' - Find a policy operation.
f27bd5ab 283 */
284
f3e786fc 285cupsd_location_t * /* O - Policy operation */
99baf768 286cupsdFindPolicyOp(cupsd_policy_t *p, /* I - Policy */
287 ipp_op_t op) /* I - IPP operation */
f27bd5ab 288{
71d7e94c 289 cupsd_location_t key, /* Search key... */
290 *po; /* Current policy operation */
53ca8055 291
292
1ff176b0 293 cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))",
f3e786fc 294 p, op, ippOpString(op));
a8c7842b 295
53ca8055 296 /*
297 * Range check...
298 */
299
71d7e94c 300 if (!p)
53ca8055 301 return (NULL);
302
303 /*
304 * Check the operation against the available policies...
305 */
306
71d7e94c 307 key.op = op;
308 if ((po = (cupsd_location_t *)cupsArrayFind(p->ops, &key)) != NULL)
309 {
310 cupsdLogMessage(CUPSD_LOG_DEBUG2,
311 "cupsdFindPolicyOp: Found exact match...");
312 return (po);
313 }
4b6bdd9f 314
71d7e94c 315 key.op = IPP_ANY_OPERATION;
316 if ((po = (cupsd_location_t *)cupsArrayFind(p->ops, &key)) != NULL)
317 {
318 cupsdLogMessage(CUPSD_LOG_DEBUG2,
319 "cupsdFindPolicyOp: Found wildcard match...");
320 return (po);
321 }
a8c7842b 322
f3e786fc 323 cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found!");
53ca8055 324
325 return (NULL);
326}
327
328
71d7e94c 329/*
330 * 'compare_ops()' - Compare two operations.
331 */
332
333static int /* O - Result of comparison */
334compare_ops(cupsd_location_t *a, /* I - First operation */
335 cupsd_location_t *b) /* I - Second operation */
336{
337 return (a->op - b->op);
338}
339
340
341/*
342 * 'compare_policies()' - Compare two policies.
343 */
344
345static int /* O - Result of comparison */
346compare_policies(cupsd_policy_t *a, /* I - First policy */
347 cupsd_policy_t *b) /* I - Second policy */
348{
349 return (strcasecmp(a->name, b->name));
350}
351
352
353/*
354 * 'hash_op()' - Generate a lookup hash for the operation.
355 */
356
357static int /* O - Hash value */
358hash_op(cupsd_location_t *op) /* I - Operation */
359{
360 return (((op->op >> 6) & 0x40) | (op->op & 0x3f));
361}
362
363
4b6bdd9f 364/*
c9d3f842 365 * End of "$Id$".
f27bd5ab 366 */