]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
75bd9771 | 2 | * "$Id: policy.c 7673 2008-06-18 22:31:26Z mike $" |
ef416fc2 | 3 | * |
4 | * Policy routines for the Common UNIX Printing System (CUPS). | |
5 | * | |
5bd77a73 | 6 | * Copyright 2007-2008 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 | ||
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 | ||
ef416fc2 | 42 | /* |
43 | * 'AddPolicy()' - Add a policy to the system. | |
44 | */ | |
45 | ||
46 | cupsd_policy_t * /* O - Policy */ | |
47 | cupsdAddPolicy(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 | ||
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 */ | |
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; |
5bd77a73 | 101 | temp->limit = CUPSD_AUTH_LIMIT_IPP; |
ef416fc2 | 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 | { | |
5bd77a73 | 123 | case CUPSD_AUTH_IP : |
ef416fc2 | 124 | cupsdAllowIP(temp, po->allow[i].mask.ip.address, |
2e4ff8af | 125 | po->allow[i].mask.ip.netmask); |
ef416fc2 | 126 | break; |
127 | ||
5bd77a73 | 128 | case CUPSD_AUTH_INTERFACE : |
ef416fc2 | 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 | { | |
5bd77a73 | 142 | case CUPSD_AUTH_IP : |
ef416fc2 | 143 | cupsdDenyIP(temp, po->deny[i].mask.ip.address, |
2e4ff8af | 144 | po->deny[i].mask.ip.netmask); |
ef416fc2 | 145 | break; |
146 | ||
5bd77a73 | 147 | case CUPSD_AUTH_INTERFACE : |
ef416fc2 | 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 | ||
168 | http_status_t /* I - 1 if OK, 0 otherwise */ | |
169 | cupsdCheckPolicy(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 | ||
211 | void | |
212 | cupsdDeleteAllPolicies(void) | |
213 | { | |
2e4ff8af MS |
214 | cupsd_policy_t *p; /* Current policy */ |
215 | cupsd_location_t *po; /* Current policy op */ | |
ba55dc12 | 216 | cupsd_printer_t *printer; /* Current printer */ |
ef416fc2 | 217 | |
218 | ||
2e4ff8af | 219 | if (!Policies) |
ef416fc2 | 220 | return; |
221 | ||
ba55dc12 MS |
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 | ||
2e4ff8af MS |
235 | for (p = (cupsd_policy_t *)cupsArrayFirst(Policies); |
236 | p; | |
237 | p = (cupsd_policy_t *)cupsArrayNext(Policies)) | |
ef416fc2 | 238 | { |
2e4ff8af MS |
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); | |
ef416fc2 | 247 | } |
248 | ||
2e4ff8af | 249 | cupsArrayDelete(Policies); |
ef416fc2 | 250 | |
2e4ff8af | 251 | Policies = NULL; |
ef416fc2 | 252 | } |
253 | ||
254 | ||
255 | /* | |
256 | * 'cupsdFindPolicy()' - Find a named policy. | |
257 | */ | |
258 | ||
259 | cupsd_policy_t * /* O - Policy */ | |
260 | cupsdFindPolicy(const char *policy) /* I - Name of policy */ | |
261 | { | |
2e4ff8af | 262 | cupsd_policy_t key; /* Search key */ |
ef416fc2 | 263 | |
264 | ||
265 | /* | |
266 | * Range check... | |
267 | */ | |
268 | ||
2e4ff8af | 269 | if (!policy) |
ef416fc2 | 270 | return (NULL); |
271 | ||
272 | /* | |
2e4ff8af | 273 | * Look it up... |
ef416fc2 | 274 | */ |
275 | ||
2e4ff8af MS |
276 | key.name = (char *)policy; |
277 | return ((cupsd_policy_t *)cupsArrayFind(Policies, &key)); | |
ef416fc2 | 278 | } |
279 | ||
280 | ||
281 | /* | |
282 | * 'cupsdFindPolicyOp()' - Find a policy operation. | |
283 | */ | |
284 | ||
285 | cupsd_location_t * /* O - Policy operation */ | |
286 | cupsdFindPolicyOp(cupsd_policy_t *p, /* I - Policy */ | |
287 | ipp_op_t op) /* I - IPP operation */ | |
288 | { | |
2e4ff8af MS |
289 | cupsd_location_t key, /* Search key... */ |
290 | *po; /* Current policy operation */ | |
ef416fc2 | 291 | |
292 | ||
75bd9771 | 293 | cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))", |
ef416fc2 | 294 | p, op, ippOpString(op)); |
295 | ||
296 | /* | |
297 | * Range check... | |
298 | */ | |
299 | ||
2e4ff8af | 300 | if (!p) |
ef416fc2 | 301 | return (NULL); |
302 | ||
303 | /* | |
304 | * Check the operation against the available policies... | |
305 | */ | |
306 | ||
2e4ff8af MS |
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 | } | |
ef416fc2 | 314 | |
2e4ff8af MS |
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 | } | |
ef416fc2 | 322 | |
323 | cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found!"); | |
324 | ||
325 | return (NULL); | |
326 | } | |
327 | ||
328 | ||
329 | /* | |
2e4ff8af MS |
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 | ||
364 | /* | |
75bd9771 | 365 | * End of "$Id: policy.c 7673 2008-06-18 22:31:26Z mike $". |
ef416fc2 | 366 | */ |