]>
Commit | Line | Data |
---|---|---|
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 | ||
37 | static int compare_ops(cupsd_location_t *a, cupsd_location_t *b); | |
38 | static int compare_policies(cupsd_policy_t *a, cupsd_policy_t *b); | |
39 | static int hash_op(cupsd_location_t *op); | |
40 | ||
41 | ||
f27bd5ab | 42 | /* |
43 | * 'AddPolicy()' - Add a policy to the system. | |
44 | */ | |
45 | ||
99baf768 | 46 | cupsd_policy_t * /* O - Policy */ |
47 | cupsdAddPolicy(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 | 75 | cupsd_location_t * /* O - New policy operation */ |
76 | cupsdAddPolicyOp(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 | 168 | http_status_t /* I - 1 if OK, 0 otherwise */ |
99baf768 | 169 | cupsdCheckPolicy(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 | ||
211 | void | |
99baf768 | 212 | cupsdDeleteAllPolicies(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 | 259 | cupsd_policy_t * /* O - Policy */ |
260 | cupsdFindPolicy(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 | 285 | cupsd_location_t * /* O - Policy operation */ |
99baf768 | 286 | cupsdFindPolicyOp(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 | ||
333 | static int /* O - Result of comparison */ | |
334 | compare_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 | ||
345 | static int /* O - Result of comparison */ | |
346 | compare_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 | ||
357 | static int /* O - Hash value */ | |
358 | hash_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 | */ |