]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/policy.c
2 * "$Id: policy.c,v 1.1.2.8 2004/06/30 21:18:31 mike Exp $"
4 * Policy routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2004 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-3142 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 */
195 * Collect info from the request...
198 op
= con
->request
->request
.op
.operation_id
;
200 if (con
->username
[0])
202 name
= con
->username
;
205 else if ((attr
= ippFindAttribute(con
->request
, "requesting-user-name",
206 IPP_TAG_NAME
)) != NULL
)
208 name
= attr
->values
[0].string
.text
;
217 LogMessage(L_DEBUG2
, "CheckPolicy: op=%04x, name=\"%s\", authenticated=%d, owner=\"%s\"",
218 op
, name
, authenticated
, owner
? owner
: "");
221 * Find a match for the operation...
224 if ((po
= FindPolicyOp(p
, op
)) == NULL
)
226 LogMessage(L_DEBUG2
, "CheckPolicy: No matching operation, returning 0!");
231 * Check the policy against the current user, etc.
234 if (po
->authenticate
&& !authenticated
)
236 LogMessage(L_DEBUG2
, "CheckPolicy: Operation requires authentication, returning 0!");
240 switch (status
= po
->order_type
)
244 if (check_op(po
, POLICY_DENY
, name
, owner
))
245 status
= POLICY_DENY
;
246 if (check_op(po
, POLICY_ALLOW
, name
, owner
))
247 status
= POLICY_ALLOW
;
251 if (check_op(po
, POLICY_ALLOW
, name
, owner
))
252 status
= POLICY_ALLOW
;
253 if (check_op(po
, POLICY_DENY
, name
, owner
))
254 status
= POLICY_DENY
;
259 * Return the status of the check...
262 LogMessage(L_DEBUG2
, "CheckPolicy: Returning %d...", !status
);
269 * 'DeleteAllPolicies()' - Delete all policies in memory.
273 DeleteAllPolicies(void)
275 int i
, j
, k
; /* Looping vars */
276 policy_t
**p
; /* Current policy */
277 policyop_t
**po
; /* Current policy operation */
278 policyname_t
*pn
; /* Current policy name */
281 if (NumPolicies
== 0)
284 for (i
= NumPolicies
, p
= Policies
; i
> 0; i
--, p
++)
286 for (j
= (*p
)->num_ops
, po
= (*p
)->ops
; j
> 0; j
--, po
++)
288 for (k
= (*po
)->num_names
, pn
= (*po
)->names
; k
> 0; k
--, pn
++)
291 if ((*po
)->num_names
> 0)
297 if ((*p
)->num_ops
> 0)
311 * 'FindPolicy()' - Find a named policy.
314 policy_t
* /* O - Policy */
315 FindPolicy(const char *policy
) /* I - Name of policy */
317 int i
; /* Looping var */
318 policy_t
**p
; /* Current policy */
329 * Check the operation against the available policies...
332 for (i
= NumPolicies
, p
= Policies
; i
> 0; i
--, p
++)
333 if (strcasecmp(policy
, (*p
)->name
) == 0)
341 * 'FindPolicyOp()' - Find a policy operation.
344 policyop_t
* /* O - Policy operation */
345 FindPolicyOp(policy_t
*p
, /* I - Policy */
346 ipp_op_t op
) /* I - IPP operation */
348 int i
; /* Looping var */
349 policyop_t
**po
; /* Current policy operation */
360 * Check the operation against the available policies...
363 for (i
= p
->num_ops
, po
= p
->ops
; i
> 0; i
--, po
++)
367 for (i
= p
->num_ops
, po
= p
->ops
; i
> 0; i
--, po
++)
368 if ((*po
)->op
== IPP_ANY_OPERATION
)
376 * 'validate_user()' - Validate the user for the request.
379 static int /* O - 1 if permitted, 0 otherwise */
380 check_group(const char *username
, /* I - Authenticated username */
381 const char *groupname
) /* I - Group name */
383 int i
; /* Looping var */
384 struct passwd
*user
; /* User info */
385 struct group
*group
; /* System group info */
386 char junk
[33]; /* MD5 password (not used) */
389 LogMessage(L_DEBUG2
, "check_group(%s, %s)\n", username
, groupname
);
395 if (username
== NULL
|| groupname
== NULL
)
399 * Check to see if the user is a member of the named group...
402 user
= getpwnam(username
);
405 group
= getgrnam(groupname
);
411 * Group exists, check it...
414 for (i
= 0; group
->gr_mem
[i
]; i
++)
415 if (strcasecmp(username
, group
->gr_mem
[i
]) == 0)
420 * Group doesn't exist or user not in group list, check the group ID
421 * against the user's group ID...
424 if (user
!= NULL
&& group
!= NULL
&& group
->gr_gid
== user
->pw_gid
)
428 * Username not found, group not found, or user is not part of the
429 * system group... Check for a user and group in the MD5 password
433 if (GetMD5Passwd(username
, groupname
, junk
) != NULL
)
437 * If we get this far, then the user isn't part of the named group...
443 #if 0 //// OLD OLD OLD OLD OLD
444 if (strcasecmp(username
, owner
) != 0 && strcasecmp(username
, "root") != 0)
447 * Not the owner or root; check to see if the user is a member of the
451 user
= getpwnam(username
);
454 for (i
= 0, j
= 0, group
= NULL
; i
< NumSystemGroups
; i
++)
456 group
= getgrnam(SystemGroups
[i
]);
461 for (j
= 0; group
->gr_mem
[j
]; j
++)
462 if (strcasecmp(username
, group
->gr_mem
[j
]) == 0)
465 if (group
->gr_mem
[j
])
472 if (user
== NULL
|| group
== NULL
||
473 (group
->gr_mem
[j
] == NULL
&& group
->gr_gid
!= user
->pw_gid
))
476 * Username not found, group not found, or user is not part of the
477 * system group... Check for a user and group in the MD5 password
481 for (i
= 0; i
< NumSystemGroups
; i
++)
482 if (GetMD5Passwd(username
, SystemGroups
[i
], junk
) != NULL
)
486 * Nope, not an MD5 user, either. Return 0 indicating no-go...
499 * 'check_op()' - Check the current operation.
502 static int /* O - 1 if match, 0 if not */
503 check_op(policyop_t
*po
, /* I - Policy operation */
504 int allow_deny
, /* I - POLICY_ALLOW or POLICY_DENY */
505 const char *name
, /* I - User name */
506 const char *owner
) /* I - Owner name */
508 int i
; /* Looping vars */
509 policyname_t
*pn
; /* Current policy name */
512 for (i
= po
->num_names
, pn
= po
->names
; i
> 0; i
--, pn
++)
514 if (pn
->allow_deny
!= allow_deny
)
517 if (!strcasecmp(pn
->name
, "@OWNER"))
519 if (owner
&& !strcasecmp(name
, owner
))
522 else if (pn
->name
[0] == '@')
524 if (check_group(name
, pn
->name
+ 1))
527 else if (!strcasecmp(name
, pn
->name
))
536 * End of "$Id: policy.c,v 1.1.2.8 2004/06/30 21:18:31 mike Exp $".