]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/policy.c
4 * Policy routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2005 by Easy Software Products, all rights reserved.
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
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
29 * Include necessary headers...
37 #endif /* HAVE_USERSEC_H */
44 static int check_group(const char *name
, const char *group
);
45 static int check_op(policyop_t
*po
, int allow_deny
, const char *name
,
50 * 'AddPolicy()' - Add a policy to the system.
53 policy_t
* /* O - Policy */
54 AddPolicy(const char *policy
) /* I - Name of policy */
56 policy_t
*temp
, /* Pointer to policy */
57 **tempa
; /* Pointer to policy array */
64 tempa
= malloc(sizeof(policy_t
*));
66 tempa
= realloc(Policies
, sizeof(policy_t
*) * (NumPolicies
+ 1));
74 if ((temp
= calloc(1, sizeof(policy_t
))) != NULL
)
76 temp
->name
= strdup(policy
);
87 * 'AddPolicyOp()' - Add an operation to a policy.
90 policyop_t
* /* O - New policy operation */
91 AddPolicyOp(policy_t
*p
, /* I - Policy */
92 policyop_t
*po
, /* I - Policy operation to copy */
93 ipp_op_t op
) /* I - IPP operation code */
95 int i
; /* Looping var */
96 policyop_t
*temp
, /* New policy operation */
97 **tempa
; /* New policy operation array */
104 tempa
= malloc(sizeof(policyop_t
*));
106 tempa
= realloc(p
->ops
, sizeof(policyop_t
*) * (p
->num_ops
+ 1));
113 if ((temp
= calloc(1, sizeof(policyop_t
))) != NULL
)
116 tempa
[p
->num_ops
] = temp
;
124 * Copy the specified policy to the new one...
127 temp
->order_type
= po
->order_type
;
128 temp
->authenticate
= po
->authenticate
;
129 for (i
= 0; i
< po
->num_names
; i
++)
130 AddPolicyOpName(temp
, po
->names
[i
].allow_deny
, po
->names
[i
].name
);
139 * 'AddPolicyOpName()' - Add a name to a policy operation.
143 AddPolicyOpName(policyop_t
*po
, /* I - Policy operation */
144 int allow_deny
, /* I - POLICY_ALLOW or POLICY_DENY */
145 const char *name
) /* I - Name to add */
147 policyname_t
*temp
; /* New name array */
150 if (po
== NULL
|| name
== NULL
)
153 if (po
->num_names
== 0)
154 temp
= malloc(sizeof(policyname_t
));
156 temp
= realloc(po
->names
, sizeof(policyname_t
) * (po
->num_names
+ 1));
161 temp
+= po
->num_names
;
164 temp
->allow_deny
= allow_deny
;
165 temp
->name
= strdup(name
);
171 * 'CheckPolicy()' - Check the IPP operation and username against a policy.
174 int /* I - 1 if OK, 0 otherwise */
175 CheckPolicy(policy_t
*p
, /* I - Policy */
176 client_t
*con
, /* I - Client connection */
177 const char *owner
) /* I - Owner of object */
179 ipp_op_t op
; /* IPP operation */
180 const char *name
; /* Username */
181 int authenticated
; /* Authenticated? */
182 ipp_attribute_t
*attr
; /* IPP attribute */
183 int status
; /* Status */
184 policyop_t
*po
; /* Current policy operation */
193 LogMessage(L_CRIT
, "CheckPolicy: p=%p, con=%p!", p
, con
);
199 * Collect info from the request...
202 op
= con
->request
->request
.op
.operation_id
;
204 if (con
->username
[0])
206 name
= con
->username
;
209 else if ((attr
= ippFindAttribute(con
->request
, "requesting-user-name",
210 IPP_TAG_NAME
)) != NULL
)
212 name
= attr
->values
[0].string
.text
;
221 LogMessage(L_DEBUG2
, "CheckPolicy: op=%04x, name=\"%s\", authenticated=%d, owner=\"%s\"",
222 op
, name
, authenticated
, owner
? owner
: "");
225 * Find a match for the operation...
228 if ((po
= FindPolicyOp(p
, op
)) == NULL
)
230 LogMessage(L_DEBUG2
, "CheckPolicy: No matching operation, returning 0!");
235 * Check the policy against the current user, etc.
238 if (po
->authenticate
&& !authenticated
)
240 LogMessage(L_DEBUG2
, "CheckPolicy: Operation requires authentication, returning 0!");
244 switch (status
= po
->order_type
)
248 if (check_op(po
, POLICY_DENY
, name
, owner
))
249 status
= POLICY_DENY
;
250 if (check_op(po
, POLICY_ALLOW
, name
, owner
))
251 status
= POLICY_ALLOW
;
255 if (check_op(po
, POLICY_ALLOW
, name
, owner
))
256 status
= POLICY_ALLOW
;
257 if (check_op(po
, POLICY_DENY
, name
, owner
))
258 status
= POLICY_DENY
;
263 * Return the status of the check...
266 LogMessage(L_DEBUG2
, "CheckPolicy: Returning %d...", !status
);
273 * 'DeleteAllPolicies()' - Delete all policies in memory.
277 DeleteAllPolicies(void)
279 int i
, j
, k
; /* Looping vars */
280 policy_t
**p
; /* Current policy */
281 policyop_t
**po
; /* Current policy operation */
282 policyname_t
*pn
; /* Current policy name */
285 if (NumPolicies
== 0)
288 for (i
= NumPolicies
, p
= Policies
; i
> 0; i
--, p
++)
290 for (j
= (*p
)->num_ops
, po
= (*p
)->ops
; j
> 0; j
--, po
++)
292 for (k
= (*po
)->num_names
, pn
= (*po
)->names
; k
> 0; k
--, pn
++)
295 if ((*po
)->num_names
> 0)
301 if ((*p
)->num_ops
> 0)
315 * 'FindPolicy()' - Find a named policy.
318 policy_t
* /* O - Policy */
319 FindPolicy(const char *policy
) /* I - Name of policy */
321 int i
; /* Looping var */
322 policy_t
**p
; /* Current policy */
333 * Check the operation against the available policies...
336 for (i
= NumPolicies
, p
= Policies
; i
> 0; i
--, p
++)
337 if (strcasecmp(policy
, (*p
)->name
) == 0)
345 * 'FindPolicyOp()' - Find a policy operation.
348 policyop_t
* /* O - Policy operation */
349 FindPolicyOp(policy_t
*p
, /* I - Policy */
350 ipp_op_t op
) /* I - IPP operation */
352 int i
; /* Looping var */
353 policyop_t
**po
; /* Current policy operation */
364 * Check the operation against the available policies...
367 for (i
= p
->num_ops
, po
= p
->ops
; i
> 0; i
--, po
++)
371 for (i
= p
->num_ops
, po
= p
->ops
; i
> 0; i
--, po
++)
372 if ((*po
)->op
== IPP_ANY_OPERATION
)
380 * 'validate_user()' - Validate the user for the request.
383 static int /* O - 1 if permitted, 0 otherwise */
384 check_group(const char *username
, /* I - Authenticated username */
385 const char *groupname
) /* I - Group name */
387 int i
; /* Looping var */
388 struct passwd
*user
; /* User info */
389 struct group
*group
; /* System group info */
390 char junk
[33]; /* MD5 password (not used) */
393 LogMessage(L_DEBUG2
, "check_group(%s, %s)\n", username
, groupname
);
399 if (username
== NULL
|| groupname
== NULL
)
403 * Check to see if the user is a member of the named group...
406 user
= getpwnam(username
);
409 group
= getgrnam(groupname
);
415 * Group exists, check it...
418 for (i
= 0; group
->gr_mem
[i
]; i
++)
419 if (strcasecmp(username
, group
->gr_mem
[i
]) == 0)
424 * Group doesn't exist or user not in group list, check the group ID
425 * against the user's group ID...
428 if (user
!= NULL
&& group
!= NULL
&& group
->gr_gid
== user
->pw_gid
)
432 * Username not found, group not found, or user is not part of the
433 * system group... Check for a user and group in the MD5 password
437 if (GetMD5Passwd(username
, groupname
, junk
) != NULL
)
441 * If we get this far, then the user isn't part of the named group...
447 #if 0 //// OLD OLD OLD OLD OLD
448 if (strcasecmp(username
, owner
) != 0 && strcasecmp(username
, "root") != 0)
451 * Not the owner or root; check to see if the user is a member of the
455 user
= getpwnam(username
);
458 for (i
= 0, j
= 0, group
= NULL
; i
< NumSystemGroups
; i
++)
460 group
= getgrnam(SystemGroups
[i
]);
465 for (j
= 0; group
->gr_mem
[j
]; j
++)
466 if (strcasecmp(username
, group
->gr_mem
[j
]) == 0)
469 if (group
->gr_mem
[j
])
476 if (user
== NULL
|| group
== NULL
||
477 (group
->gr_mem
[j
] == NULL
&& group
->gr_gid
!= user
->pw_gid
))
480 * Username not found, group not found, or user is not part of the
481 * system group... Check for a user and group in the MD5 password
485 for (i
= 0; i
< NumSystemGroups
; i
++)
486 if (GetMD5Passwd(username
, SystemGroups
[i
], junk
) != NULL
)
490 * Nope, not an MD5 user, either. Return 0 indicating no-go...
503 * 'check_op()' - Check the current operation.
506 static int /* O - 1 if match, 0 if not */
507 check_op(policyop_t
*po
, /* I - Policy operation */
508 int allow_deny
, /* I - POLICY_ALLOW or POLICY_DENY */
509 const char *name
, /* I - User name */
510 const char *owner
) /* I - Owner name */
512 int i
; /* Looping vars */
513 policyname_t
*pn
; /* Current policy name */
516 for (i
= po
->num_names
, pn
= po
->names
; i
> 0; i
--, pn
++)
518 if (pn
->allow_deny
!= allow_deny
)
521 if (!strcasecmp(pn
->name
, "@OWNER"))
523 if (owner
&& !strcasecmp(name
, owner
))
526 else if (pn
->name
[0] == '@')
528 if (check_group(name
, pn
->name
+ 1))
531 else if (!strcasecmp(name
, pn
->name
))