xref: /aosp_15_r20/external/libcups/scheduler/policy.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Policy routines for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2011, 2014 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 1997-2006 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker  */
9*5e7646d2SAndroid Build Coastguard Worker 
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker  */
13*5e7646d2SAndroid Build Coastguard Worker 
14*5e7646d2SAndroid Build Coastguard Worker #include "cupsd.h"
15*5e7646d2SAndroid Build Coastguard Worker #include <pwd.h>
16*5e7646d2SAndroid Build Coastguard Worker 
17*5e7646d2SAndroid Build Coastguard Worker 
18*5e7646d2SAndroid Build Coastguard Worker /*
19*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
20*5e7646d2SAndroid Build Coastguard Worker  */
21*5e7646d2SAndroid Build Coastguard Worker 
22*5e7646d2SAndroid Build Coastguard Worker static int	compare_ops(cupsd_location_t *a, cupsd_location_t *b);
23*5e7646d2SAndroid Build Coastguard Worker static int	compare_policies(cupsd_policy_t *a, cupsd_policy_t *b);
24*5e7646d2SAndroid Build Coastguard Worker static void	free_policy(cupsd_policy_t *p);
25*5e7646d2SAndroid Build Coastguard Worker static int	hash_op(cupsd_location_t *op);
26*5e7646d2SAndroid Build Coastguard Worker 
27*5e7646d2SAndroid Build Coastguard Worker 
28*5e7646d2SAndroid Build Coastguard Worker /*
29*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdAddPolicy()' - Add a policy to the system.
30*5e7646d2SAndroid Build Coastguard Worker  */
31*5e7646d2SAndroid Build Coastguard Worker 
32*5e7646d2SAndroid Build Coastguard Worker cupsd_policy_t *			/* O - Policy */
cupsdAddPolicy(const char * policy)33*5e7646d2SAndroid Build Coastguard Worker cupsdAddPolicy(const char *policy)	/* I - Name of policy */
34*5e7646d2SAndroid Build Coastguard Worker {
35*5e7646d2SAndroid Build Coastguard Worker   cupsd_policy_t	*temp;		/* Pointer to policy */
36*5e7646d2SAndroid Build Coastguard Worker 
37*5e7646d2SAndroid Build Coastguard Worker 
38*5e7646d2SAndroid Build Coastguard Worker   if (!policy)
39*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
40*5e7646d2SAndroid Build Coastguard Worker 
41*5e7646d2SAndroid Build Coastguard Worker   if (!Policies)
42*5e7646d2SAndroid Build Coastguard Worker     Policies = cupsArrayNew3((cups_array_func_t)compare_policies, NULL,
43*5e7646d2SAndroid Build Coastguard Worker 			     (cups_ahash_func_t)NULL, 0,
44*5e7646d2SAndroid Build Coastguard Worker 			     (cups_acopy_func_t)NULL,
45*5e7646d2SAndroid Build Coastguard Worker 			     (cups_afree_func_t)free_policy);
46*5e7646d2SAndroid Build Coastguard Worker 
47*5e7646d2SAndroid Build Coastguard Worker   if (!Policies)
48*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
49*5e7646d2SAndroid Build Coastguard Worker 
50*5e7646d2SAndroid Build Coastguard Worker   if ((temp = calloc(1, sizeof(cupsd_policy_t))) != NULL)
51*5e7646d2SAndroid Build Coastguard Worker   {
52*5e7646d2SAndroid Build Coastguard Worker     cupsdSetString(&temp->name, policy);
53*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(Policies, temp);
54*5e7646d2SAndroid Build Coastguard Worker   }
55*5e7646d2SAndroid Build Coastguard Worker 
56*5e7646d2SAndroid Build Coastguard Worker   return (temp);
57*5e7646d2SAndroid Build Coastguard Worker }
58*5e7646d2SAndroid Build Coastguard Worker 
59*5e7646d2SAndroid Build Coastguard Worker 
60*5e7646d2SAndroid Build Coastguard Worker /*
61*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdAddPolicyOp()' - Add an operation to a policy.
62*5e7646d2SAndroid Build Coastguard Worker  */
63*5e7646d2SAndroid Build Coastguard Worker 
64*5e7646d2SAndroid Build Coastguard Worker cupsd_location_t *			/* O - New policy operation */
cupsdAddPolicyOp(cupsd_policy_t * p,cupsd_location_t * po,ipp_op_t op)65*5e7646d2SAndroid Build Coastguard Worker cupsdAddPolicyOp(cupsd_policy_t   *p,	/* I - Policy */
66*5e7646d2SAndroid Build Coastguard Worker                  cupsd_location_t *po,	/* I - Policy operation to copy */
67*5e7646d2SAndroid Build Coastguard Worker                  ipp_op_t         op)	/* I - IPP operation code */
68*5e7646d2SAndroid Build Coastguard Worker {
69*5e7646d2SAndroid Build Coastguard Worker   cupsd_location_t	*temp;		/* New policy operation */
70*5e7646d2SAndroid Build Coastguard Worker 
71*5e7646d2SAndroid Build Coastguard Worker 
72*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddPolicyOp(p=%p, po=%p, op=%x(%s))",
73*5e7646d2SAndroid Build Coastguard Worker                   p, po, op, ippOpString(op));
74*5e7646d2SAndroid Build Coastguard Worker 
75*5e7646d2SAndroid Build Coastguard Worker   if (!p)
76*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
77*5e7646d2SAndroid Build Coastguard Worker 
78*5e7646d2SAndroid Build Coastguard Worker   if (!p->ops)
79*5e7646d2SAndroid Build Coastguard Worker     p->ops = cupsArrayNew3((cups_array_func_t)compare_ops, NULL,
80*5e7646d2SAndroid Build Coastguard Worker                            (cups_ahash_func_t)hash_op, 128,
81*5e7646d2SAndroid Build Coastguard Worker 			   (cups_acopy_func_t)NULL,
82*5e7646d2SAndroid Build Coastguard Worker 			   (cups_afree_func_t)cupsdFreeLocation);
83*5e7646d2SAndroid Build Coastguard Worker 
84*5e7646d2SAndroid Build Coastguard Worker   if (!p->ops)
85*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
86*5e7646d2SAndroid Build Coastguard Worker 
87*5e7646d2SAndroid Build Coastguard Worker   if ((temp = cupsdCopyLocation(po)) != NULL)
88*5e7646d2SAndroid Build Coastguard Worker   {
89*5e7646d2SAndroid Build Coastguard Worker     temp->op    = op;
90*5e7646d2SAndroid Build Coastguard Worker     temp->limit = CUPSD_AUTH_LIMIT_IPP;
91*5e7646d2SAndroid Build Coastguard Worker 
92*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(p->ops, temp);
93*5e7646d2SAndroid Build Coastguard Worker   }
94*5e7646d2SAndroid Build Coastguard Worker 
95*5e7646d2SAndroid Build Coastguard Worker   return (temp);
96*5e7646d2SAndroid Build Coastguard Worker }
97*5e7646d2SAndroid Build Coastguard Worker 
98*5e7646d2SAndroid Build Coastguard Worker 
99*5e7646d2SAndroid Build Coastguard Worker /*
100*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdCheckPolicy()' - Check the IPP operation and username against a policy.
101*5e7646d2SAndroid Build Coastguard Worker  */
102*5e7646d2SAndroid Build Coastguard Worker 
103*5e7646d2SAndroid Build Coastguard Worker http_status_t				/* I - 1 if OK, 0 otherwise */
cupsdCheckPolicy(cupsd_policy_t * p,cupsd_client_t * con,const char * owner)104*5e7646d2SAndroid Build Coastguard Worker cupsdCheckPolicy(cupsd_policy_t *p,	/* I - Policy */
105*5e7646d2SAndroid Build Coastguard Worker                  cupsd_client_t *con,	/* I - Client connection */
106*5e7646d2SAndroid Build Coastguard Worker 	         const char     *owner)	/* I - Owner of object */
107*5e7646d2SAndroid Build Coastguard Worker {
108*5e7646d2SAndroid Build Coastguard Worker   cupsd_location_t	*po;		/* Current policy operation */
109*5e7646d2SAndroid Build Coastguard Worker 
110*5e7646d2SAndroid Build Coastguard Worker 
111*5e7646d2SAndroid Build Coastguard Worker  /*
112*5e7646d2SAndroid Build Coastguard Worker   * Range check...
113*5e7646d2SAndroid Build Coastguard Worker   */
114*5e7646d2SAndroid Build Coastguard Worker 
115*5e7646d2SAndroid Build Coastguard Worker   if (!p || !con)
116*5e7646d2SAndroid Build Coastguard Worker   {
117*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p.", p, con);
118*5e7646d2SAndroid Build Coastguard Worker 
119*5e7646d2SAndroid Build Coastguard Worker     return ((http_status_t)0);
120*5e7646d2SAndroid Build Coastguard Worker   }
121*5e7646d2SAndroid Build Coastguard Worker 
122*5e7646d2SAndroid Build Coastguard Worker  /*
123*5e7646d2SAndroid Build Coastguard Worker   * Find a match for the operation...
124*5e7646d2SAndroid Build Coastguard Worker   */
125*5e7646d2SAndroid Build Coastguard Worker 
126*5e7646d2SAndroid Build Coastguard Worker   if ((po = cupsdFindPolicyOp(p, con->request->request.op.operation_id)) == NULL)
127*5e7646d2SAndroid Build Coastguard Worker   {
128*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckPolicy: No matching operation, returning 0.");
129*5e7646d2SAndroid Build Coastguard Worker     return ((http_status_t)0);
130*5e7646d2SAndroid Build Coastguard Worker   }
131*5e7646d2SAndroid Build Coastguard Worker 
132*5e7646d2SAndroid Build Coastguard Worker   con->best = po;
133*5e7646d2SAndroid Build Coastguard Worker 
134*5e7646d2SAndroid Build Coastguard Worker  /*
135*5e7646d2SAndroid Build Coastguard Worker   * Return the status of the check...
136*5e7646d2SAndroid Build Coastguard Worker   */
137*5e7646d2SAndroid Build Coastguard Worker 
138*5e7646d2SAndroid Build Coastguard Worker   return (cupsdIsAuthorized(con, owner));
139*5e7646d2SAndroid Build Coastguard Worker }
140*5e7646d2SAndroid Build Coastguard Worker 
141*5e7646d2SAndroid Build Coastguard Worker 
142*5e7646d2SAndroid Build Coastguard Worker /*
143*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdDeleteAllPolicies()' - Delete all policies in memory.
144*5e7646d2SAndroid Build Coastguard Worker  */
145*5e7646d2SAndroid Build Coastguard Worker 
146*5e7646d2SAndroid Build Coastguard Worker void
cupsdDeleteAllPolicies(void)147*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteAllPolicies(void)
148*5e7646d2SAndroid Build Coastguard Worker {
149*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*printer;	/* Current printer */
150*5e7646d2SAndroid Build Coastguard Worker 
151*5e7646d2SAndroid Build Coastguard Worker 
152*5e7646d2SAndroid Build Coastguard Worker   if (!Policies)
153*5e7646d2SAndroid Build Coastguard Worker     return;
154*5e7646d2SAndroid Build Coastguard Worker 
155*5e7646d2SAndroid Build Coastguard Worker  /*
156*5e7646d2SAndroid Build Coastguard Worker   * First clear the policy pointers for all printers...
157*5e7646d2SAndroid Build Coastguard Worker   */
158*5e7646d2SAndroid Build Coastguard Worker 
159*5e7646d2SAndroid Build Coastguard Worker   for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
160*5e7646d2SAndroid Build Coastguard Worker        printer;
161*5e7646d2SAndroid Build Coastguard Worker        printer = (cupsd_printer_t *)cupsArrayNext(Printers))
162*5e7646d2SAndroid Build Coastguard Worker     printer->op_policy_ptr = NULL;
163*5e7646d2SAndroid Build Coastguard Worker 
164*5e7646d2SAndroid Build Coastguard Worker   DefaultPolicyPtr = NULL;
165*5e7646d2SAndroid Build Coastguard Worker 
166*5e7646d2SAndroid Build Coastguard Worker  /*
167*5e7646d2SAndroid Build Coastguard Worker   * Then free all of the policies...
168*5e7646d2SAndroid Build Coastguard Worker   */
169*5e7646d2SAndroid Build Coastguard Worker 
170*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(Policies);
171*5e7646d2SAndroid Build Coastguard Worker 
172*5e7646d2SAndroid Build Coastguard Worker   Policies = NULL;
173*5e7646d2SAndroid Build Coastguard Worker }
174*5e7646d2SAndroid Build Coastguard Worker 
175*5e7646d2SAndroid Build Coastguard Worker 
176*5e7646d2SAndroid Build Coastguard Worker /*
177*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdFindPolicy()' - Find a named policy.
178*5e7646d2SAndroid Build Coastguard Worker  */
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker cupsd_policy_t *			/* O - Policy */
cupsdFindPolicy(const char * policy)181*5e7646d2SAndroid Build Coastguard Worker cupsdFindPolicy(const char *policy)	/* I - Name of policy */
182*5e7646d2SAndroid Build Coastguard Worker {
183*5e7646d2SAndroid Build Coastguard Worker   cupsd_policy_t	key;		/* Search key */
184*5e7646d2SAndroid Build Coastguard Worker 
185*5e7646d2SAndroid Build Coastguard Worker 
186*5e7646d2SAndroid Build Coastguard Worker  /*
187*5e7646d2SAndroid Build Coastguard Worker   * Range check...
188*5e7646d2SAndroid Build Coastguard Worker   */
189*5e7646d2SAndroid Build Coastguard Worker 
190*5e7646d2SAndroid Build Coastguard Worker   if (!policy)
191*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
192*5e7646d2SAndroid Build Coastguard Worker 
193*5e7646d2SAndroid Build Coastguard Worker  /*
194*5e7646d2SAndroid Build Coastguard Worker   * Look it up...
195*5e7646d2SAndroid Build Coastguard Worker   */
196*5e7646d2SAndroid Build Coastguard Worker 
197*5e7646d2SAndroid Build Coastguard Worker   key.name = (char *)policy;
198*5e7646d2SAndroid Build Coastguard Worker   return ((cupsd_policy_t *)cupsArrayFind(Policies, &key));
199*5e7646d2SAndroid Build Coastguard Worker }
200*5e7646d2SAndroid Build Coastguard Worker 
201*5e7646d2SAndroid Build Coastguard Worker 
202*5e7646d2SAndroid Build Coastguard Worker /*
203*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdFindPolicyOp()' - Find a policy operation.
204*5e7646d2SAndroid Build Coastguard Worker  */
205*5e7646d2SAndroid Build Coastguard Worker 
206*5e7646d2SAndroid Build Coastguard Worker cupsd_location_t *			/* O - Policy operation */
cupsdFindPolicyOp(cupsd_policy_t * p,ipp_op_t op)207*5e7646d2SAndroid Build Coastguard Worker cupsdFindPolicyOp(cupsd_policy_t *p,	/* I - Policy */
208*5e7646d2SAndroid Build Coastguard Worker                   ipp_op_t       op)	/* I - IPP operation */
209*5e7646d2SAndroid Build Coastguard Worker {
210*5e7646d2SAndroid Build Coastguard Worker   cupsd_location_t	key,		/* Search key... */
211*5e7646d2SAndroid Build Coastguard Worker 			*po;		/* Current policy operation */
212*5e7646d2SAndroid Build Coastguard Worker 
213*5e7646d2SAndroid Build Coastguard Worker 
214*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))",
215*5e7646d2SAndroid Build Coastguard Worker                   p, op, ippOpString(op));
216*5e7646d2SAndroid Build Coastguard Worker 
217*5e7646d2SAndroid Build Coastguard Worker  /*
218*5e7646d2SAndroid Build Coastguard Worker   * Range check...
219*5e7646d2SAndroid Build Coastguard Worker   */
220*5e7646d2SAndroid Build Coastguard Worker 
221*5e7646d2SAndroid Build Coastguard Worker   if (!p)
222*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
223*5e7646d2SAndroid Build Coastguard Worker 
224*5e7646d2SAndroid Build Coastguard Worker  /*
225*5e7646d2SAndroid Build Coastguard Worker   * Check the operation against the available policies...
226*5e7646d2SAndroid Build Coastguard Worker   */
227*5e7646d2SAndroid Build Coastguard Worker 
228*5e7646d2SAndroid Build Coastguard Worker   key.op = op;
229*5e7646d2SAndroid Build Coastguard Worker   if ((po = (cupsd_location_t *)cupsArrayFind(p->ops, &key)) != NULL)
230*5e7646d2SAndroid Build Coastguard Worker   {
231*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG2,
232*5e7646d2SAndroid Build Coastguard Worker 		    "cupsdFindPolicyOp: Found exact match...");
233*5e7646d2SAndroid Build Coastguard Worker     return (po);
234*5e7646d2SAndroid Build Coastguard Worker   }
235*5e7646d2SAndroid Build Coastguard Worker 
236*5e7646d2SAndroid Build Coastguard Worker   key.op = IPP_ANY_OPERATION;
237*5e7646d2SAndroid Build Coastguard Worker   if ((po = (cupsd_location_t *)cupsArrayFind(p->ops, &key)) != NULL)
238*5e7646d2SAndroid Build Coastguard Worker   {
239*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG2,
240*5e7646d2SAndroid Build Coastguard Worker 		    "cupsdFindPolicyOp: Found wildcard match...");
241*5e7646d2SAndroid Build Coastguard Worker     return (po);
242*5e7646d2SAndroid Build Coastguard Worker   }
243*5e7646d2SAndroid Build Coastguard Worker 
244*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found.");
245*5e7646d2SAndroid Build Coastguard Worker 
246*5e7646d2SAndroid Build Coastguard Worker   return (NULL);
247*5e7646d2SAndroid Build Coastguard Worker }
248*5e7646d2SAndroid Build Coastguard Worker 
249*5e7646d2SAndroid Build Coastguard Worker 
250*5e7646d2SAndroid Build Coastguard Worker /*
251*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdGetPrivateAttrs()' - Get the private attributes for the current
252*5e7646d2SAndroid Build Coastguard Worker  *                            request.
253*5e7646d2SAndroid Build Coastguard Worker  */
254*5e7646d2SAndroid Build Coastguard Worker 
255*5e7646d2SAndroid Build Coastguard Worker cups_array_t *				/* O - Array or NULL for no restrictions */
cupsdGetPrivateAttrs(cupsd_policy_t * policy,cupsd_client_t * con,cupsd_printer_t * printer,const char * owner)256*5e7646d2SAndroid Build Coastguard Worker cupsdGetPrivateAttrs(
257*5e7646d2SAndroid Build Coastguard Worker     cupsd_policy_t  *policy,		/* I - Policy */
258*5e7646d2SAndroid Build Coastguard Worker     cupsd_client_t  *con,		/* I - Client connection */
259*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *printer,		/* I - Printer, if any */
260*5e7646d2SAndroid Build Coastguard Worker     const char      *owner)		/* I - Owner of object */
261*5e7646d2SAndroid Build Coastguard Worker {
262*5e7646d2SAndroid Build Coastguard Worker   char		*name;			/* Current name in access list */
263*5e7646d2SAndroid Build Coastguard Worker   cups_array_t	*access_ptr,		/* Access array */
264*5e7646d2SAndroid Build Coastguard Worker 		*attrs_ptr;		/* Attributes array */
265*5e7646d2SAndroid Build Coastguard Worker   const char	*username;		/* Username associated with request */
266*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* Attribute from request */
267*5e7646d2SAndroid Build Coastguard Worker   struct passwd	*pw;			/* User info */
268*5e7646d2SAndroid Build Coastguard Worker 
269*5e7646d2SAndroid Build Coastguard Worker 
270*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
271*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
272*5e7646d2SAndroid Build Coastguard Worker                   "cupsdGetPrivateAttrs(policy=%p(%s), con=%p(%d), "
273*5e7646d2SAndroid Build Coastguard Worker 		  "printer=%p(%s), owner=\"%s\")", policy, policy->name, con,
274*5e7646d2SAndroid Build Coastguard Worker 		  con->number, printer, printer ? printer->name : "", owner);
275*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
276*5e7646d2SAndroid Build Coastguard Worker 
277*5e7646d2SAndroid Build Coastguard Worker   if (!policy)
278*5e7646d2SAndroid Build Coastguard Worker   {
279*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdGetPrivateAttrs: policy=%p, con=%p, printer=%p, owner=\"%s\", DefaultPolicyPtr=%p: This should never happen, please report a bug.", policy, con, printer, owner, DefaultPolicyPtr);
280*5e7646d2SAndroid Build Coastguard Worker     policy = DefaultPolicyPtr;
281*5e7646d2SAndroid Build Coastguard Worker   }
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker  /*
284*5e7646d2SAndroid Build Coastguard Worker   * Get the access and attributes lists that correspond to the request...
285*5e7646d2SAndroid Build Coastguard Worker   */
286*5e7646d2SAndroid Build Coastguard Worker 
287*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
288*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: %s",
289*5e7646d2SAndroid Build Coastguard Worker                   ippOpString(con->request->request.op.operation_id));
290*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
291*5e7646d2SAndroid Build Coastguard Worker 
292*5e7646d2SAndroid Build Coastguard Worker   switch (con->request->request.op.operation_id)
293*5e7646d2SAndroid Build Coastguard Worker   {
294*5e7646d2SAndroid Build Coastguard Worker     case IPP_GET_SUBSCRIPTIONS :
295*5e7646d2SAndroid Build Coastguard Worker     case IPP_GET_SUBSCRIPTION_ATTRIBUTES :
296*5e7646d2SAndroid Build Coastguard Worker     case IPP_GET_NOTIFICATIONS :
297*5e7646d2SAndroid Build Coastguard Worker         access_ptr = policy->sub_access;
298*5e7646d2SAndroid Build Coastguard Worker 	attrs_ptr  = policy->sub_attrs;
299*5e7646d2SAndroid Build Coastguard Worker 	break;
300*5e7646d2SAndroid Build Coastguard Worker 
301*5e7646d2SAndroid Build Coastguard Worker     default :
302*5e7646d2SAndroid Build Coastguard Worker         access_ptr = policy->job_access;
303*5e7646d2SAndroid Build Coastguard Worker 	attrs_ptr  = policy->job_attrs;
304*5e7646d2SAndroid Build Coastguard Worker         break;
305*5e7646d2SAndroid Build Coastguard Worker   }
306*5e7646d2SAndroid Build Coastguard Worker 
307*5e7646d2SAndroid Build Coastguard Worker  /*
308*5e7646d2SAndroid Build Coastguard Worker   * If none of the attributes are private, return NULL now...
309*5e7646d2SAndroid Build Coastguard Worker   */
310*5e7646d2SAndroid Build Coastguard Worker 
311*5e7646d2SAndroid Build Coastguard Worker   if ((name = (char *)cupsArrayFirst(attrs_ptr)) != NULL &&
312*5e7646d2SAndroid Build Coastguard Worker       !_cups_strcasecmp(name, "none"))
313*5e7646d2SAndroid Build Coastguard Worker   {
314*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
315*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning NULL.");
316*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
317*5e7646d2SAndroid Build Coastguard Worker 
318*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
319*5e7646d2SAndroid Build Coastguard Worker   }
320*5e7646d2SAndroid Build Coastguard Worker 
321*5e7646d2SAndroid Build Coastguard Worker  /*
322*5e7646d2SAndroid Build Coastguard Worker   * Otherwise check the user against the access list...
323*5e7646d2SAndroid Build Coastguard Worker   */
324*5e7646d2SAndroid Build Coastguard Worker 
325*5e7646d2SAndroid Build Coastguard Worker   if (con->username[0])
326*5e7646d2SAndroid Build Coastguard Worker     username = con->username;
327*5e7646d2SAndroid Build Coastguard Worker   else if ((attr = ippFindAttribute(con->request, "requesting-user-name",
328*5e7646d2SAndroid Build Coastguard Worker                                     IPP_TAG_NAME)) != NULL)
329*5e7646d2SAndroid Build Coastguard Worker     username = attr->values[0].string.text;
330*5e7646d2SAndroid Build Coastguard Worker   else
331*5e7646d2SAndroid Build Coastguard Worker     username = "anonymous";
332*5e7646d2SAndroid Build Coastguard Worker 
333*5e7646d2SAndroid Build Coastguard Worker   if (username[0])
334*5e7646d2SAndroid Build Coastguard Worker   {
335*5e7646d2SAndroid Build Coastguard Worker     pw = getpwnam(username);
336*5e7646d2SAndroid Build Coastguard Worker     endpwent();
337*5e7646d2SAndroid Build Coastguard Worker   }
338*5e7646d2SAndroid Build Coastguard Worker   else
339*5e7646d2SAndroid Build Coastguard Worker     pw = NULL;
340*5e7646d2SAndroid Build Coastguard Worker 
341*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
342*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: username=\"%s\"",
343*5e7646d2SAndroid Build Coastguard Worker                   username);
344*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
345*5e7646d2SAndroid Build Coastguard Worker 
346*5e7646d2SAndroid Build Coastguard Worker  /*
347*5e7646d2SAndroid Build Coastguard Worker   * Otherwise check the user against the access list...
348*5e7646d2SAndroid Build Coastguard Worker   */
349*5e7646d2SAndroid Build Coastguard Worker 
350*5e7646d2SAndroid Build Coastguard Worker   for (name = (char *)cupsArrayFirst(access_ptr);
351*5e7646d2SAndroid Build Coastguard Worker        name;
352*5e7646d2SAndroid Build Coastguard Worker        name = (char *)cupsArrayNext(access_ptr))
353*5e7646d2SAndroid Build Coastguard Worker   {
354*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
355*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: name=%s", name);
356*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
357*5e7646d2SAndroid Build Coastguard Worker 
358*5e7646d2SAndroid Build Coastguard Worker     if (printer && !_cups_strcasecmp(name, "@ACL"))
359*5e7646d2SAndroid Build Coastguard Worker     {
360*5e7646d2SAndroid Build Coastguard Worker       char	*acl;			/* Current ACL user/group */
361*5e7646d2SAndroid Build Coastguard Worker 
362*5e7646d2SAndroid Build Coastguard Worker       for (acl = (char *)cupsArrayFirst(printer->users);
363*5e7646d2SAndroid Build Coastguard Worker 	   acl;
364*5e7646d2SAndroid Build Coastguard Worker 	   acl = (char *)cupsArrayNext(printer->users))
365*5e7646d2SAndroid Build Coastguard Worker       {
366*5e7646d2SAndroid Build Coastguard Worker 	if (acl[0] == '@')
367*5e7646d2SAndroid Build Coastguard Worker 	{
368*5e7646d2SAndroid Build Coastguard Worker 	 /*
369*5e7646d2SAndroid Build Coastguard Worker 	  * Check group membership...
370*5e7646d2SAndroid Build Coastguard Worker 	  */
371*5e7646d2SAndroid Build Coastguard Worker 
372*5e7646d2SAndroid Build Coastguard Worker 	  if (cupsdCheckGroup(username, pw, acl + 1))
373*5e7646d2SAndroid Build Coastguard Worker 	    break;
374*5e7646d2SAndroid Build Coastguard Worker 	}
375*5e7646d2SAndroid Build Coastguard Worker 	else if (acl[0] == '#')
376*5e7646d2SAndroid Build Coastguard Worker 	{
377*5e7646d2SAndroid Build Coastguard Worker 	 /*
378*5e7646d2SAndroid Build Coastguard Worker 	  * Check UUID...
379*5e7646d2SAndroid Build Coastguard Worker 	  */
380*5e7646d2SAndroid Build Coastguard Worker 
381*5e7646d2SAndroid Build Coastguard Worker 	  if (cupsdCheckGroup(username, pw, acl))
382*5e7646d2SAndroid Build Coastguard Worker 	    break;
383*5e7646d2SAndroid Build Coastguard Worker 	}
384*5e7646d2SAndroid Build Coastguard Worker 	else if (!_cups_strcasecmp(username, acl))
385*5e7646d2SAndroid Build Coastguard Worker 	  break;
386*5e7646d2SAndroid Build Coastguard Worker       }
387*5e7646d2SAndroid Build Coastguard Worker     }
388*5e7646d2SAndroid Build Coastguard Worker     else if (owner && !_cups_strcasecmp(name, "@OWNER") &&
389*5e7646d2SAndroid Build Coastguard Worker              !_cups_strcasecmp(username, owner))
390*5e7646d2SAndroid Build Coastguard Worker     {
391*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
392*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG2,
393*5e7646d2SAndroid Build Coastguard Worker 		      "cupsdGetPrivateAttrs: Returning NULL.");
394*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
395*5e7646d2SAndroid Build Coastguard Worker 
396*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
397*5e7646d2SAndroid Build Coastguard Worker     }
398*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(name, "@SYSTEM"))
399*5e7646d2SAndroid Build Coastguard Worker     {
400*5e7646d2SAndroid Build Coastguard Worker       int i;				/* Looping var */
401*5e7646d2SAndroid Build Coastguard Worker 
402*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < NumSystemGroups; i ++)
403*5e7646d2SAndroid Build Coastguard Worker 	if (cupsdCheckGroup(username, pw, SystemGroups[i]))
404*5e7646d2SAndroid Build Coastguard Worker 	{
405*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
406*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_DEBUG2,
407*5e7646d2SAndroid Build Coastguard Worker 	                  "cupsdGetPrivateAttrs: Returning NULL.");
408*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
409*5e7646d2SAndroid Build Coastguard Worker 
410*5e7646d2SAndroid Build Coastguard Worker 	  return (NULL);
411*5e7646d2SAndroid Build Coastguard Worker 	}
412*5e7646d2SAndroid Build Coastguard Worker     }
413*5e7646d2SAndroid Build Coastguard Worker     else if (name[0] == '@')
414*5e7646d2SAndroid Build Coastguard Worker     {
415*5e7646d2SAndroid Build Coastguard Worker       if (cupsdCheckGroup(username, pw, name + 1))
416*5e7646d2SAndroid Build Coastguard Worker       {
417*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
418*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_DEBUG2,
419*5e7646d2SAndroid Build Coastguard Worker 	                "cupsdGetPrivateAttrs: Returning NULL.");
420*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
421*5e7646d2SAndroid Build Coastguard Worker 
422*5e7646d2SAndroid Build Coastguard Worker 	return (NULL);
423*5e7646d2SAndroid Build Coastguard Worker       }
424*5e7646d2SAndroid Build Coastguard Worker     }
425*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(username, name))
426*5e7646d2SAndroid Build Coastguard Worker     {
427*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
428*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning NULL.");
429*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
430*5e7646d2SAndroid Build Coastguard Worker 
431*5e7646d2SAndroid Build Coastguard Worker       return (NULL);
432*5e7646d2SAndroid Build Coastguard Worker     }
433*5e7646d2SAndroid Build Coastguard Worker   }
434*5e7646d2SAndroid Build Coastguard Worker 
435*5e7646d2SAndroid Build Coastguard Worker  /*
436*5e7646d2SAndroid Build Coastguard Worker   * No direct access, so return private attributes list...
437*5e7646d2SAndroid Build Coastguard Worker   */
438*5e7646d2SAndroid Build Coastguard Worker 
439*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
440*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning list.");
441*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
442*5e7646d2SAndroid Build Coastguard Worker 
443*5e7646d2SAndroid Build Coastguard Worker   return (attrs_ptr);
444*5e7646d2SAndroid Build Coastguard Worker }
445*5e7646d2SAndroid Build Coastguard Worker 
446*5e7646d2SAndroid Build Coastguard Worker 
447*5e7646d2SAndroid Build Coastguard Worker /*
448*5e7646d2SAndroid Build Coastguard Worker  * 'compare_ops()' - Compare two operations.
449*5e7646d2SAndroid Build Coastguard Worker  */
450*5e7646d2SAndroid Build Coastguard Worker 
451*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Result of comparison */
compare_ops(cupsd_location_t * a,cupsd_location_t * b)452*5e7646d2SAndroid Build Coastguard Worker compare_ops(cupsd_location_t *a,	/* I - First operation */
453*5e7646d2SAndroid Build Coastguard Worker             cupsd_location_t *b)	/* I - Second operation */
454*5e7646d2SAndroid Build Coastguard Worker {
455*5e7646d2SAndroid Build Coastguard Worker   return (a->op - b->op);
456*5e7646d2SAndroid Build Coastguard Worker }
457*5e7646d2SAndroid Build Coastguard Worker 
458*5e7646d2SAndroid Build Coastguard Worker 
459*5e7646d2SAndroid Build Coastguard Worker /*
460*5e7646d2SAndroid Build Coastguard Worker  * 'compare_policies()' - Compare two policies.
461*5e7646d2SAndroid Build Coastguard Worker  */
462*5e7646d2SAndroid Build Coastguard Worker 
463*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Result of comparison */
compare_policies(cupsd_policy_t * a,cupsd_policy_t * b)464*5e7646d2SAndroid Build Coastguard Worker compare_policies(cupsd_policy_t *a,	/* I - First policy */
465*5e7646d2SAndroid Build Coastguard Worker                  cupsd_policy_t *b)	/* I - Second policy */
466*5e7646d2SAndroid Build Coastguard Worker {
467*5e7646d2SAndroid Build Coastguard Worker   return (_cups_strcasecmp(a->name, b->name));
468*5e7646d2SAndroid Build Coastguard Worker }
469*5e7646d2SAndroid Build Coastguard Worker 
470*5e7646d2SAndroid Build Coastguard Worker 
471*5e7646d2SAndroid Build Coastguard Worker /*
472*5e7646d2SAndroid Build Coastguard Worker  * 'free_policy()' - Free the memory used by a policy.
473*5e7646d2SAndroid Build Coastguard Worker  */
474*5e7646d2SAndroid Build Coastguard Worker 
475*5e7646d2SAndroid Build Coastguard Worker static void
free_policy(cupsd_policy_t * p)476*5e7646d2SAndroid Build Coastguard Worker free_policy(cupsd_policy_t *p)		/* I - Policy to free */
477*5e7646d2SAndroid Build Coastguard Worker {
478*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(p->job_access);
479*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(p->job_attrs);
480*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(p->sub_access);
481*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(p->sub_attrs);
482*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(p->ops);
483*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->name);
484*5e7646d2SAndroid Build Coastguard Worker   free(p);
485*5e7646d2SAndroid Build Coastguard Worker }
486*5e7646d2SAndroid Build Coastguard Worker 
487*5e7646d2SAndroid Build Coastguard Worker 
488*5e7646d2SAndroid Build Coastguard Worker /*
489*5e7646d2SAndroid Build Coastguard Worker  * 'hash_op()' - Generate a lookup hash for the operation.
490*5e7646d2SAndroid Build Coastguard Worker  */
491*5e7646d2SAndroid Build Coastguard Worker 
492*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Hash value */
hash_op(cupsd_location_t * op)493*5e7646d2SAndroid Build Coastguard Worker hash_op(cupsd_location_t *op)		/* I - Operation */
494*5e7646d2SAndroid Build Coastguard Worker {
495*5e7646d2SAndroid Build Coastguard Worker   return (((op->op >> 6) & 0x40) | (op->op & 0x3f));
496*5e7646d2SAndroid Build Coastguard Worker }
497