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