]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/policy.c
Remove all of the Subversion keywords from various source files.
[thirdparty/cups.git] / scheduler / policy.c
index 25204ee89a51907dd91d2985a98ecbf8135fdece..9a68b1a97b582a769e8bf2fc1033759924524d85 100644 (file)
@@ -1,26 +1,14 @@
 /*
- * "$Id: policy.c 6895 2007-08-30 00:09:27Z mike $"
+ * Policy routines for the CUPS scheduler.
  *
- *   Policy routines for the Common UNIX Printing System (CUPS).
+ * Copyright 2007-2011, 2014 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products, all rights reserved.
  *
- *   Copyright 2007 by Apple Inc.
- *   Copyright 1997-2006 by Easy Software Products, all rights reserved.
- *
- *   These coded instructions, statements, and computer programs are the
- *   property of Apple Inc. and are protected by Federal copyright
- *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- *   which should have been included with this file.  If this file is
- *   file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- *   cupsdAddPolicy()         - Add a policy to the system.
- *   cupsdAddPolicyOp()       - Add an operation to a policy.
- *   cupsdCheckPolicy()       - Check the IPP operation and username against
- *                              a policy.
- *   cupsdDeleteAllPolicies() - Delete all policies in memory.
- *   cupsdFindPolicy()        - Find a named policy.
- *   cupsdFindPolicyOp()      - Find a policy operation.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file.  If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
  */
 
 /*
@@ -28,6 +16,7 @@
  */
 
 #include "cupsd.h"
+#include <pwd.h>
 
 
 /*
 
 static int     compare_ops(cupsd_location_t *a, cupsd_location_t *b);
 static int     compare_policies(cupsd_policy_t *a, cupsd_policy_t *b);
+static void    free_policy(cupsd_policy_t *p);
 static int     hash_op(cupsd_location_t *op);
 
 
 /*
- * 'AddPolicy()' - Add a policy to the system.
+ * 'cupsdAddPolicy()' - Add a policy to the system.
  */
 
 cupsd_policy_t *                       /* O - Policy */
@@ -53,7 +43,10 @@ cupsdAddPolicy(const char *policy)   /* I - Name of policy */
     return (NULL);
 
   if (!Policies)
-    Policies = cupsArrayNew((cups_array_func_t)compare_policies, NULL);
+    Policies = cupsArrayNew3((cups_array_func_t)compare_policies, NULL,
+                            (cups_ahash_func_t)NULL, 0,
+                            (cups_acopy_func_t)NULL,
+                            (cups_afree_func_t)free_policy);
 
   if (!Policies)
     return (NULL);
@@ -77,9 +70,7 @@ cupsdAddPolicyOp(cupsd_policy_t   *p, /* I - Policy */
                  cupsd_location_t *po, /* I - Policy operation to copy */
                  ipp_op_t         op)  /* I - IPP operation code */
 {
-  int                  i;              /* Looping var */
   cupsd_location_t     *temp;          /* New policy operation */
-  char                 name[1024];     /* Interface name */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddPolicyOp(p=%p, po=%p, op=%x(%s))",
@@ -89,72 +80,20 @@ cupsdAddPolicyOp(cupsd_policy_t   *p,       /* I - Policy */
     return (NULL);
 
   if (!p->ops)
-    p->ops = cupsArrayNew2((cups_array_func_t)compare_ops, NULL,
-                           (cups_ahash_func_t)hash_op, 128);
+    p->ops = cupsArrayNew3((cups_array_func_t)compare_ops, NULL,
+                           (cups_ahash_func_t)hash_op, 128,
+                          (cups_acopy_func_t)NULL,
+                          (cups_afree_func_t)cupsdFreeLocation);
 
   if (!p->ops)
     return (NULL);
 
-  if ((temp = calloc(1, sizeof(cupsd_location_t))) != NULL)
+  if ((temp = cupsdCopyLocation(po)) != NULL)
   {
     temp->op    = op;
-    temp->limit = AUTH_LIMIT_IPP;
+    temp->limit = CUPSD_AUTH_LIMIT_IPP;
 
     cupsArrayAdd(p->ops, temp);
-
-    if (po)
-    {
-     /*
-      * Copy the specified policy to the new one...
-      */
-
-      temp->order_type = po->order_type;
-      temp->type       = po->type;
-      temp->level      = po->level;
-      temp->satisfy    = po->satisfy;
-      temp->encryption = po->encryption;
-
-      for (i = 0; i < po->num_names; i ++)
-        cupsdAddName(temp, po->names[i]);
-
-      for (i = 0; i < po->num_allow; i ++)
-        switch (po->allow[i].type)
-       {
-         case AUTH_IP :
-             cupsdAllowIP(temp, po->allow[i].mask.ip.address,
-                          po->allow[i].mask.ip.netmask);
-             break;
-
-          case AUTH_INTERFACE :
-             snprintf(name, sizeof(name), "@IF(%s)",
-                      po->allow[i].mask.name.name);
-              cupsdAllowHost(temp, name);
-             break;
-
-          default :
-              cupsdAllowHost(temp, po->allow[i].mask.name.name);
-             break;
-        }
-
-      for (i = 0; i < po->num_deny; i ++)
-        switch (po->deny[i].type)
-       {
-         case AUTH_IP :
-             cupsdDenyIP(temp, po->deny[i].mask.ip.address,
-                         po->deny[i].mask.ip.netmask);
-             break;
-
-          case AUTH_INTERFACE :
-             snprintf(name, sizeof(name), "@IF(%s)",
-                      po->deny[i].mask.name.name);
-              cupsdDenyHost(temp, name);
-             break;
-
-          default :
-              cupsdDenyHost(temp, po->deny[i].mask.name.name);
-             break;
-        }
-    }
   }
 
   return (temp);
@@ -179,7 +118,7 @@ cupsdCheckPolicy(cupsd_policy_t *p, /* I - Policy */
 
   if (!p || !con)
   {
-    cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p!", p, con);
+    cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p.", p, con);
 
     return ((http_status_t)0);
   }
@@ -190,7 +129,7 @@ cupsdCheckPolicy(cupsd_policy_t *p, /* I - Policy */
 
   if ((po = cupsdFindPolicyOp(p, con->request->request.op.operation_id)) == NULL)
   {
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckPolicy: No matching operation, returning 0!");
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckPolicy: No matching operation, returning 0.");
     return ((http_status_t)0);
   }
 
@@ -211,26 +150,26 @@ cupsdCheckPolicy(cupsd_policy_t *p,       /* I - Policy */
 void
 cupsdDeleteAllPolicies(void)
 {
-  cupsd_policy_t       *p;             /* Current policy */
-  cupsd_location_t     *po;            /* Current policy op */
+  cupsd_printer_t      *printer;       /* Current printer */
 
 
   if (!Policies)
     return;
 
-  for (p = (cupsd_policy_t *)cupsArrayFirst(Policies);
-       p;
-       p = (cupsd_policy_t *)cupsArrayNext(Policies))
-  {
-    for (po = (cupsd_location_t *)cupsArrayFirst(p->ops);
-         po;
-        po = (cupsd_location_t *)cupsArrayNext(p->ops))
-      cupsdDeleteLocation(po);
-
-    cupsArrayDelete(p->ops);
-    cupsdClearString(&p->name);
-    free(p);
-  }
+ /*
+  * First clear the policy pointers for all printers...
+  */
+
+  for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
+       printer;
+       printer = (cupsd_printer_t *)cupsArrayNext(Printers))
+    printer->op_policy_ptr = NULL;
+
+  DefaultPolicyPtr = NULL;
+
+ /*
+  * Then free all of the policies...
+  */
 
   cupsArrayDelete(Policies);
 
@@ -276,7 +215,7 @@ cupsdFindPolicyOp(cupsd_policy_t *p,        /* I - Policy */
                        *po;            /* Current policy operation */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))\n",
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))",
                   p, op, ippOpString(op));
 
  /*
@@ -306,12 +245,209 @@ cupsdFindPolicyOp(cupsd_policy_t *p,     /* I - Policy */
     return (po);
   }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found!");
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found.");
 
   return (NULL);
 }
 
 
+/*
+ * 'cupsdGetPrivateAttrs()' - Get the private attributes for the current
+ *                            request.
+ */
+
+cups_array_t *                         /* O - Array or NULL for no restrictions */
+cupsdGetPrivateAttrs(
+    cupsd_policy_t  *policy,           /* I - Policy */
+    cupsd_client_t  *con,              /* I - Client connection */
+    cupsd_printer_t *printer,          /* I - Printer, if any */
+    const char      *owner)            /* I - Owner of object */
+{
+  char         *name;                  /* Current name in access list */
+  cups_array_t *access_ptr,            /* Access array */
+               *attrs_ptr;             /* Attributes array */
+  const char   *username;              /* Username associated with request */
+  ipp_attribute_t *attr;               /* Attribute from request */
+  struct passwd        *pw;                    /* User info */
+
+
+#ifdef DEBUG
+  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                  "cupsdGetPrivateAttrs(policy=%p(%s), con=%p(%d), "
+                 "printer=%p(%s), owner=\"%s\")", policy, policy->name, con,
+                 con->number, printer, printer ? printer->name : "", owner);
+#endif /* DEBUG */
+
+  if (!policy)
+  {
+    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);
+    policy = DefaultPolicyPtr;
+  }
+
+ /*
+  * Get the access and attributes lists that correspond to the request...
+  */
+
+#ifdef DEBUG
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: %s",
+                  ippOpString(con->request->request.op.operation_id));
+#endif /* DEBUG */
+
+  switch (con->request->request.op.operation_id)
+  {
+    case IPP_GET_SUBSCRIPTIONS :
+    case IPP_GET_SUBSCRIPTION_ATTRIBUTES :
+    case IPP_GET_NOTIFICATIONS :
+        access_ptr = policy->sub_access;
+       attrs_ptr  = policy->sub_attrs;
+       break;
+
+    default :
+        access_ptr = policy->job_access;
+       attrs_ptr  = policy->job_attrs;
+        break;
+  }
+
+ /*
+  * If none of the attributes are private, return NULL now...
+  */
+
+  if ((name = (char *)cupsArrayFirst(attrs_ptr)) != NULL &&
+      !_cups_strcasecmp(name, "none"))
+  {
+#ifdef DEBUG
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning NULL.");
+#endif /* DEBUG */
+
+    return (NULL);
+  }
+
+ /*
+  * Otherwise check the user against the access list...
+  */
+
+  if (con->username[0])
+    username = con->username;
+  else if ((attr = ippFindAttribute(con->request, "requesting-user-name",
+                                    IPP_TAG_NAME)) != NULL)
+    username = attr->values[0].string.text;
+  else
+    username = "anonymous";
+
+  if (username[0])
+  {
+    pw = getpwnam(username);
+    endpwent();
+  }
+  else
+    pw = NULL;
+
+#ifdef DEBUG
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: username=\"%s\"",
+                  username);
+#endif /* DEBUG */
+
+ /*
+  * Otherwise check the user against the access list...
+  */
+
+  for (name = (char *)cupsArrayFirst(access_ptr);
+       name;
+       name = (char *)cupsArrayNext(access_ptr))
+  {
+#ifdef DEBUG
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: name=%s", name);
+#endif /* DEBUG */
+
+    if (printer && !_cups_strcasecmp(name, "@ACL"))
+    {
+      char     *acl;                   /* Current ACL user/group */
+
+      for (acl = (char *)cupsArrayFirst(printer->users);
+          acl;
+          acl = (char *)cupsArrayNext(printer->users))
+      {
+       if (acl[0] == '@')
+       {
+        /*
+         * Check group membership...
+         */
+
+         if (cupsdCheckGroup(username, pw, acl + 1))
+           break;
+       }
+       else if (acl[0] == '#')
+       {
+        /*
+         * Check UUID...
+         */
+
+         if (cupsdCheckGroup(username, pw, acl))
+           break;
+       }
+       else if (!_cups_strcasecmp(username, acl))
+         break;
+      }
+    }
+    else if (owner && !_cups_strcasecmp(name, "@OWNER") &&
+             !_cups_strcasecmp(username, owner))
+    {
+#ifdef DEBUG
+      cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                     "cupsdGetPrivateAttrs: Returning NULL.");
+#endif /* DEBUG */
+
+      return (NULL);
+    }
+    else if (!_cups_strcasecmp(name, "@SYSTEM"))
+    {
+      int i;                           /* Looping var */
+
+      for (i = 0; i < NumSystemGroups; i ++)
+       if (cupsdCheckGroup(username, pw, SystemGroups[i]))
+       {
+#ifdef DEBUG
+         cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                         "cupsdGetPrivateAttrs: Returning NULL.");
+#endif /* DEBUG */
+
+         return (NULL);
+       }
+    }
+    else if (name[0] == '@')
+    {
+      if (cupsdCheckGroup(username, pw, name + 1))
+      {
+#ifdef DEBUG
+        cupsdLogMessage(CUPSD_LOG_DEBUG2,
+                       "cupsdGetPrivateAttrs: Returning NULL.");
+#endif /* DEBUG */
+
+       return (NULL);
+      }
+    }
+    else if (!_cups_strcasecmp(username, name))
+    {
+#ifdef DEBUG
+      cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning NULL.");
+#endif /* DEBUG */
+
+      return (NULL);
+    }
+  }
+
+ /*
+  * No direct access, so return private attributes list...
+  */
+
+#ifdef DEBUG
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdGetPrivateAttrs: Returning list.");
+#endif /* DEBUG */
+
+  return (attrs_ptr);
+}
+
+
 /*
  * 'compare_ops()' - Compare two operations.
  */
@@ -332,21 +468,33 @@ static int                                /* O - Result of comparison */
 compare_policies(cupsd_policy_t *a,    /* I - First policy */
                  cupsd_policy_t *b)    /* I - Second policy */
 {
-  return (strcasecmp(a->name, b->name));
+  return (_cups_strcasecmp(a->name, b->name));
 }
 
 
 /*
- * 'hash_op()' - Generate a lookup hash for the operation.
+ * 'free_policy()' - Free the memory used by a policy.
  */
 
-static int                             /* O - Hash value */
-hash_op(cupsd_location_t *op)          /* I - Operation */
+static void
+free_policy(cupsd_policy_t *p)         /* I - Policy to free */
 {
-  return (((op->op >> 6) & 0x40) | (op->op & 0x3f));
+  cupsArrayDelete(p->job_access);
+  cupsArrayDelete(p->job_attrs);
+  cupsArrayDelete(p->sub_access);
+  cupsArrayDelete(p->sub_attrs);
+  cupsArrayDelete(p->ops);
+  cupsdClearString(&p->name);
+  free(p);
 }
 
 
 /*
- * End of "$Id: policy.c 6895 2007-08-30 00:09:27Z mike $".
+ * 'hash_op()' - Generate a lookup hash for the operation.
  */
+
+static int                             /* O - Hash value */
+hash_op(cupsd_location_t *op)          /* I - Operation */
+{
+  return (((op->op >> 6) & 0x40) | (op->op & 0x3f));
+}