]>
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 */ | |
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 | ||
245 | cupsd_policy_t * /* O - Policy */ | |
246 | cupsdFindPolicy(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 | ||
271 | cupsd_location_t * /* O - Policy operation */ | |
272 | cupsdFindPolicyOp(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 | ||
75bd9771 | 279 | cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))", |
ef416fc2 | 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 | ||
319 | static int /* O - Result of comparison */ | |
320 | compare_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 | ||
331 | static int /* O - Result of comparison */ | |
332 | compare_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 | ||
343 | static int /* O - Hash value */ | |
344 | hash_op(cupsd_location_t *op) /* I - Operation */ | |
345 | { | |
346 | return (((op->op >> 6) & 0x40) | (op->op & 0x3f)); | |
347 | } | |
348 | ||
349 | ||
350 | /* | |
75bd9771 | 351 | * End of "$Id: policy.c 7673 2008-06-18 22:31:26Z mike $". |
ef416fc2 | 352 | */ |