]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/policy.c
Only add certificates for authenticated users and only add root
[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 *
c9d3f842 6 * Copyright 1997-2005 by Easy Software Products, all rights reserved.
f27bd5ab 7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
c9d3f842 18 * Hollywood, Maryland 20636 USA
f27bd5ab 19 *
9639c4de 20 * Voice: (301) 373-9600
f27bd5ab 21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
26 */
27
28/*
29 * Include necessary headers...
30 */
31
32#include "cupsd.h"
f27bd5ab 33#include <grp.h>
34#ifdef HAVE_USERSEC_H
35# include <usersec.h>
36#endif /* HAVE_USERSEC_H */
37
38
39/*
40 * Local functions...
41 */
42
4b6bdd9f 43static int check_op(policyop_t *po, int allow_deny, const char *name,
44 const char *owner);
53ca8055 45
f27bd5ab 46
47/*
48 * 'AddPolicy()' - Add a policy to the system.
49 */
50
51policy_t * /* O - Policy */
52AddPolicy(const char *policy) /* I - Name of policy */
53{
4b6bdd9f 54 policy_t *temp, /* Pointer to policy */
55 **tempa; /* Pointer to policy array */
53ca8055 56
57
58 if (policy == NULL)
59 return (NULL);
60
61 if (NumPolicies == 0)
4b6bdd9f 62 tempa = malloc(sizeof(policy_t *));
53ca8055 63 else
4b6bdd9f 64 tempa = realloc(Policies, sizeof(policy_t *) * (NumPolicies + 1));
53ca8055 65
4b6bdd9f 66 if (tempa == NULL)
67 return (NULL);
68
69 Policies = tempa;
70 tempa += NumPolicies;
71
72 if ((temp = calloc(1, sizeof(policy_t))) != NULL)
53ca8055 73 {
4b6bdd9f 74 temp->name = strdup(policy);
75 *tempa = temp;
53ca8055 76
4b6bdd9f 77 NumPolicies ++;
53ca8055 78 }
79
80 return (temp);
f27bd5ab 81}
82
83
84/*
85 * 'AddPolicyOp()' - Add an operation to a policy.
86 */
87
88policyop_t * /* O - New policy operation */
4b6bdd9f 89AddPolicyOp(policy_t *p, /* I - Policy */
90 policyop_t *po, /* I - Policy operation to copy */
91 ipp_op_t op) /* I - IPP operation code */
f27bd5ab 92{
4b6bdd9f 93 int i; /* Looping var */
94 policyop_t *temp, /* New policy operation */
95 **tempa; /* New policy operation array */
53ca8055 96
97
98 if (p == NULL)
99 return (NULL);
100
101 if (p->num_ops == 0)
4b6bdd9f 102 tempa = malloc(sizeof(policyop_t *));
53ca8055 103 else
4b6bdd9f 104 tempa = realloc(p->ops, sizeof(policyop_t *) * (p->num_ops + 1));
53ca8055 105
4b6bdd9f 106 if (tempa == NULL)
107 return (NULL);
108
109 p->ops = tempa;
110
111 if ((temp = calloc(1, sizeof(policyop_t))) != NULL)
53ca8055 112 {
4b6bdd9f 113 p->ops = tempa;
114 tempa[p->num_ops] = temp;
53ca8055 115 p->num_ops ++;
116
53ca8055 117 temp->op = op;
4b6bdd9f 118
119 if (po)
120 {
121 /*
122 * Copy the specified policy to the new one...
123 */
124
125 temp->order_type = po->order_type;
126 temp->authenticate = po->authenticate;
127 for (i = 0; i < po->num_names; i ++)
128 AddPolicyOpName(temp, po->names[i].allow_deny, po->names[i].name);
129 }
53ca8055 130 }
131
132 return (temp);
f27bd5ab 133}
134
135
136/*
137 * 'AddPolicyOpName()' - Add a name to a policy operation.
138 */
139
140void
141AddPolicyOpName(policyop_t *po, /* I - Policy operation */
4b6bdd9f 142 int allow_deny, /* I - POLICY_ALLOW or POLICY_DENY */
f27bd5ab 143 const char *name) /* I - Name to add */
144{
4b6bdd9f 145 policyname_t *temp; /* New name array */
53ca8055 146
147
148 if (po == NULL || name == NULL)
149 return;
150
151 if (po->num_names == 0)
4b6bdd9f 152 temp = malloc(sizeof(policyname_t));
53ca8055 153 else
4b6bdd9f 154 temp = realloc(po->names, sizeof(policyname_t) * (po->num_names + 1));
53ca8055 155
156 if (temp != NULL)
157 {
158 po->names = temp;
159 temp += po->num_names;
160 po->num_names ++;
161
4b6bdd9f 162 temp->allow_deny = allow_deny;
163 temp->name = strdup(name);
53ca8055 164 }
f27bd5ab 165}
166
167
168/*
169 * 'CheckPolicy()' - Check the IPP operation and username against a policy.
170 */
171
172int /* I - 1 if OK, 0 otherwise */
173CheckPolicy(policy_t *p, /* I - Policy */
bd5510a5 174 client_t *con, /* I - Client connection */
53ca8055 175 const char *owner) /* I - Owner of object */
f27bd5ab 176{
bd5510a5 177 ipp_op_t op; /* IPP operation */
178 const char *name; /* Username */
179 int authenticated; /* Authenticated? */
180 ipp_attribute_t *attr; /* IPP attribute */
4b6bdd9f 181 int status; /* Status */
53ca8055 182 policyop_t *po; /* Current policy operation */
53ca8055 183
184
185 /*
186 * Range check...
187 */
188
bd5510a5 189 if (!p || !con)
fd09381d 190 {
191 LogMessage(L_CRIT, "CheckPolicy: p=%p, con=%p!", p, con);
192
53ca8055 193 return (0);
fd09381d 194 }
53ca8055 195
bd5510a5 196 /*
197 * Collect info from the request...
198 */
199
200 op = con->request->request.op.operation_id;
201
202 if (con->username[0])
203 {
204 name = con->username;
205 authenticated = 1;
206 }
207 else if ((attr = ippFindAttribute(con->request, "requesting-user-name",
208 IPP_TAG_NAME)) != NULL)
209 {
210 name = attr->values[0].string.text;
211 authenticated = 0;
212 }
213 else
214 {
215 name = "anonymous";
216 authenticated = 0;
217 }
218
5934328c 219 LogMessage(L_DEBUG2, "CheckPolicy: op=%04x, name=\"%s\", authenticated=%d, owner=\"%s\"",
220 op, name, authenticated, owner ? owner : "");
221
53ca8055 222 /*
4b6bdd9f 223 * Find a match for the operation...
53ca8055 224 */
225
4b6bdd9f 226 if ((po = FindPolicyOp(p, op)) == NULL)
5934328c 227 {
228 LogMessage(L_DEBUG2, "CheckPolicy: No matching operation, returning 0!");
4b6bdd9f 229 return (0);
5934328c 230 }
4b6bdd9f 231
232 /*
233 * Check the policy against the current user, etc.
234 */
235
236 if (po->authenticate && !authenticated)
5934328c 237 {
238 LogMessage(L_DEBUG2, "CheckPolicy: Operation requires authentication, returning 0!");
4b6bdd9f 239 return (0);
5934328c 240 }
4b6bdd9f 241
242 switch (status = po->order_type)
243 {
244 default :
245 case POLICY_ALLOW :
246 if (check_op(po, POLICY_DENY, name, owner))
247 status = POLICY_DENY;
248 if (check_op(po, POLICY_ALLOW, name, owner))
249 status = POLICY_ALLOW;
250 break;
251
252 case POLICY_DENY :
253 if (check_op(po, POLICY_ALLOW, name, owner))
254 status = POLICY_ALLOW;
255 if (check_op(po, POLICY_DENY, name, owner))
256 status = POLICY_DENY;
257 break;
258 }
53ca8055 259
260 /*
4b6bdd9f 261 * Return the status of the check...
53ca8055 262 */
263
5934328c 264 LogMessage(L_DEBUG2, "CheckPolicy: Returning %d...", !status);
265
4b6bdd9f 266 return (!status);
f27bd5ab 267}
268
269
270/*
271 * 'DeleteAllPolicies()' - Delete all policies in memory.
272 */
273
274void
275DeleteAllPolicies(void)
276{
4b6bdd9f 277 int i, j, k; /* Looping vars */
278 policy_t **p; /* Current policy */
279 policyop_t **po; /* Current policy operation */
280 policyname_t *pn; /* Current policy name */
53ca8055 281
282
283 if (NumPolicies == 0)
284 return;
285
286 for (i = NumPolicies, p = Policies; i > 0; i --, p ++)
287 {
4b6bdd9f 288 for (j = (*p)->num_ops, po = (*p)->ops; j > 0; j --, po ++)
53ca8055 289 {
4b6bdd9f 290 for (k = (*po)->num_names, pn = (*po)->names; k > 0; k --, pn ++)
291 free(pn->name);
292
293 if ((*po)->num_names > 0)
294 free((*po)->names);
53ca8055 295
4b6bdd9f 296 free(*po);
53ca8055 297 }
298
4b6bdd9f 299 if ((*p)->num_ops > 0)
300 free((*p)->ops);
301
302 free(*p);
53ca8055 303 }
304
305 free(Policies);
306
307 NumPolicies = 0;
308 Policies = NULL;
f27bd5ab 309}
310
311
312/*
313 * 'FindPolicy()' - Find a named policy.
314 */
315
316policy_t * /* O - Policy */
317FindPolicy(const char *policy) /* I - Name of policy */
318{
53ca8055 319 int i; /* Looping var */
4b6bdd9f 320 policy_t **p; /* Current policy */
53ca8055 321
322
323 /*
324 * Range check...
325 */
326
327 if (policy == NULL)
328 return (NULL);
329
330 /*
331 * Check the operation against the available policies...
332 */
333
334 for (i = NumPolicies, p = Policies; i > 0; i --, p ++)
4b6bdd9f 335 if (strcasecmp(policy, (*p)->name) == 0)
336 return (*p);
53ca8055 337
338 return (NULL);
f27bd5ab 339}
340
341
342/*
343 * 'FindPolicyOp()' - Find a policy operation.
344 */
345
346policyop_t * /* O - Policy operation */
347FindPolicyOp(policy_t *p, /* I - Policy */
348 ipp_op_t op) /* I - IPP operation */
349{
53ca8055 350 int i; /* Looping var */
4b6bdd9f 351 policyop_t **po; /* Current policy operation */
53ca8055 352
353
354 /*
355 * Range check...
356 */
357
358 if (p == NULL)
359 return (NULL);
360
361 /*
362 * Check the operation against the available policies...
363 */
364
365 for (i = p->num_ops, po = p->ops; i > 0; i --, po ++)
4b6bdd9f 366 if ((*po)->op == op)
367 return (*po);
368
369 for (i = p->num_ops, po = p->ops; i > 0; i --, po ++)
370 if ((*po)->op == IPP_ANY_OPERATION)
371 return (*po);
53ca8055 372
373 return (NULL);
374}
375
376
f27bd5ab 377/*
4b6bdd9f 378 * 'check_op()' - Check the current operation.
379 */
380
381static int /* O - 1 if match, 0 if not */
382check_op(policyop_t *po, /* I - Policy operation */
383 int allow_deny, /* I - POLICY_ALLOW or POLICY_DENY */
384 const char *name, /* I - User name */
385 const char *owner) /* I - Owner name */
386{
9d0c9f28 387 int i, j; /* Looping vars */
4b6bdd9f 388 policyname_t *pn; /* Current policy name */
9d0c9f28 389 struct passwd *pw; /* User's password entry */
4b6bdd9f 390
391
9d0c9f28 392 pw = getpwnam(name);
393 endpwent();
394
4b6bdd9f 395 for (i = po->num_names, pn = po->names; i > 0; i --, pn ++)
396 {
397 if (pn->allow_deny != allow_deny)
398 continue;
399
400 if (!strcasecmp(pn->name, "@OWNER"))
401 {
402 if (owner && !strcasecmp(name, owner))
403 return (1);
404 }
9d0c9f28 405 else if (!strcasecmp(pn->name, "@SYSTEM"))
406 {
407 for (j = 0; j < NumSystemGroups; j ++)
408 if (cupsdCheckGroup(name, pw, SystemGroups[j]))
409 return (1);
410 }
4b6bdd9f 411 else if (pn->name[0] == '@')
412 {
9d0c9f28 413 if (cupsdCheckGroup(name, pw, pn->name + 1))
4b6bdd9f 414 return (1);
415 }
416 else if (!strcasecmp(name, pn->name))
417 return (1);
418 }
419
420 return (0);
421}
422
423
424/*
c9d3f842 425 * End of "$Id$".
f27bd5ab 426 */