]> andersk Git - moira.git/blobdiff - server/qsetup.pc
register_user() on a registered Kerberos-only account should provide you
[moira.git] / server / qsetup.pc
index b99c8fdce84c127b02c9ef78134ced6a126a1446..040d9533da8b32d7a1cc6c952f3af41dcb4fce65 100644 (file)
@@ -32,7 +32,8 @@ EXEC SQL END DECLARE SECTION;
 
 EXEC SQL WHENEVER SQLERROR DO dbmserr();
 
-
+int hostname_check(char *name);
+int hostinfo_check(char *name, int num);
 int prefetch_value(struct query *q, char **argv, client *cl);
 int check_nfs(int mach_idx, char *name, char *access);
 
@@ -60,6 +61,20 @@ int setup_ausr(struct query *q, char *argv[], client *cl)
     row = 2;
   else
     row = 1;
+
+  if (q->version > 2)
+    {
+      if (strlen(argv[row + 3]) + strlen(argv[row + 4]) +
+         strlen(argv[row + 5]) + 2 > USERS_FULLNAME_SIZE)
+       return MR_ARG_TOO_LONG;
+    }
+  else
+    {
+      if (strlen(argv[row + 2]) + strlen(argv[row + 3]) +
+         strlen(argv[row + 4]) + 2 > USERS_FULLNAME_SIZE)
+       return MR_ARG_TOO_LONG;
+    }
+
   if (!strcmp(argv[row], UNIQUE_UID) || atoi(argv[row]) == -1)
     {
       if ((err = set_next_object_id("unix_uid", USERS_TABLE, 1)))
@@ -76,6 +91,12 @@ int setup_ausr(struct query *q, char *argv[], client *cl)
   if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
     return mr_errcode;
 
+  /* If this is an UPDATE query, we're done. */
+  if (row == 2)
+    return MR_SUCCESS;
+
+  /* For an add query, we need to fill in the creator id. */
+  sprintf(argv[q->argc + q->vcnt + 1], "%d", cl->client_id);
   return MR_SUCCESS;
 }
 
@@ -88,17 +109,19 @@ int setup_dusr(struct query *q, char *argv[], client *cl)
 {
   EXEC SQL BEGIN DECLARE SECTION;
   int flag, id, cnt;
+  char resv[USERS_RESERVATIONS_SIZE];
   EXEC SQL END DECLARE SECTION;
 
   id = *(int *)argv[0];
 
-  /* For now, only allow users to be deleted if their status is 0 */
-  EXEC SQL SELECT status INTO :flag FROM users WHERE users_id = :id;
-  if (flag != 0 && flag != 4)
+  /* For now, only allow users to be deleted if their status is 0
+   * and we have no reservations about deleting them.
+   */
+  EXEC SQL SELECT status, reservations INTO :flag, :resv
+    FROM users WHERE users_id = :id;
+  if ((flag != 0 && flag != 4) || *resv)
     return MR_IN_USE;
 
-  EXEC SQL DELETE FROM quota WHERE entity_id = :id AND type = 'USER';
-  EXEC SQL DELETE FROM krbmap WHERE users_id = :id;
   EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
     WHERE member_id = :id AND member_type = 'USER';
   if (cnt > 0)
@@ -121,31 +144,9 @@ int setup_dusr(struct query *q, char *argv[], client *cl)
     return MR_IN_USE;
   if (dbms_errno)
     return mr_errcode;
-  return MR_SUCCESS;
-}
-
-
-/* setup_spop: verify that there is already a valid POP machine_id in the
- * pop_id field.  Also take care of keeping track of the post office usage.
- */
-int setup_spop(struct query *q, char *argv[], client *cl)
-{
-  EXEC SQL BEGIN DECLARE SECTION;
-  int id, mid;
-  char type[USERS_POTYPE_SIZE];
-  EXEC SQL END DECLARE SECTION;
 
-  id = *(int *)argv[0];
-  EXEC SQL SELECT potype, pop_id INTO :type, :mid FROM users
-    WHERE users_id = :id;
-  if (sqlca.sqlerrd[2] == 0)
-    return MR_MACHINE;
-  EXEC SQL SELECT mach_id INTO :mid FROM machine
-    WHERE mach_id = :mid;
-  if (sqlca.sqlerrd[2] == 0)
-    return MR_MACHINE;
-  if (strcmp(strtrim(type), "POP"))
-    set_pop_usage(mid, 1);
+  EXEC SQL DELETE FROM quota WHERE entity_id = :id AND type = 'USER';
+  EXEC SQL DELETE FROM krbmap WHERE users_id = :id;
   return MR_SUCCESS;
 }
 
@@ -203,15 +204,19 @@ int setup_dmac(struct query *q, char *argv[], client *cl)
     WHERE mach_id = :id;
   if (cnt > 0)
     return MR_IN_USE;
-  EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printcap
+  EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printers
     WHERE mach_id = :id;
   if (cnt > 0)
     return MR_IN_USE;
-  EXEC SQL SELECT COUNT(quotaserver) INTO :cnt FROM printcap
-    WHERE quotaserver = :id;
+  EXEC SQL SELECT COUNT(rm) INTO :cnt FROM printers
+    WHERE rm = :id;
+  if (cnt > 0)
+    return MR_IN_USE;
+  EXEC SQL SELECT COUNT(rq) INTO :cnt FROM printers
+    WHERE rq = :id;
   if (cnt > 0)
     return MR_IN_USE;
-  EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM palladium
+  EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printservers
     WHERE mach_id = :id;
   if (cnt > 0)
     return MR_IN_USE;
@@ -219,13 +224,70 @@ int setup_dmac(struct query *q, char *argv[], client *cl)
     WHERE mach_id = :id;
   if (cnt > 0)
     return MR_IN_USE;
+  EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
+    WHERE member_type = 'MACHINE' and member_id = :id;
+  if (cnt > 0)
+    return MR_IN_USE;
 
   EXEC SQL DELETE FROM mcmap WHERE mach_id = :id;
+  if (dbms_errno)
+    return mr_errcode;
+
+  EXEC SQL DELETE FROM mcntmap WHERE mach_id = :id;
   if (dbms_errno)
     return mr_errcode;
   return MR_SUCCESS;
 }
 
+/* setup_asnt - verify that the data entered for the subnet is sane.
+ * In particular, make sure that the "low" and "high" addresses are
+ * correctly ordered, i.e., high > low.
+ */
+
+int setup_asnt(struct query *q, char *argv[], client *cl)
+{
+  int high, low, row, status;
+  char *account_number;
+
+  /* Check for asnt or usnt. */
+  if (q->type == APPEND)
+    row = 0;
+  else
+    row = 1;
+
+  low = atoi(argv[row + 7]);
+  high = atoi(argv[row + 8]);
+  status = atoi(argv[row + 2]);
+  account_number = argv[row + 4];
+  
+  /* Don't allow Private subnets to be created without a valid billing
+   * number.
+   */
+  if (status == SNET_STATUS_PRIVATE_10MBPS || 
+      status == SNET_STATUS_PRIVATE_100MBPS ||
+      status == SNET_STATUS_PRIVATE_1000MBPS)
+    {
+      EXEC SQL SELECT account_number FROM accountnumbers
+       WHERE account_number = :account_number;
+      if (sqlca.sqlcode == SQL_NO_MATCH)
+       return MR_ACCOUNT_NUMBER;
+    }
+      
+  /* Special case 0.0.0.0 and 255.255.255.255 */
+  if (!(low == 0 || low == -1 || high == 0 || high == -1))
+    if (low > high)
+      return MR_ADDRESS;
+
+  /* If this is update_subnet, we're done. */
+  if (row == 1)
+    return MR_SUCCESS;
+
+  /* For an add_subnet query, allocate and fill in a new snet_id */
+  if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
+    return mr_errcode;
+
+  return MR_SUCCESS;
+}
 
 /* setup_dsnt - verify that the subnet is no longer being referenced
  * and may safely be deleted.
@@ -277,17 +339,20 @@ int setup_dclu(struct query *q, char *argv[], client *cl)
  * a -1 there.  Remember that this is also used for ulis, with the indexes
  * at 6 & 7.  Also check that the list name does not contain uppercase
  * characters, control characters, @, or :.
+ *
+ *  Newlines in list descriptions do bad things to the aliases file
+ *  moira generates, so make sure the description doesn't contain any, too.
  */
 
 static int badlistchars[] = {
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
-  1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
+  1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, /* P - _ */
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -301,7 +366,8 @@ static int badlistchars[] = {
 int setup_alis(struct query *q, char *argv[], client *cl)
 {
   EXEC SQL BEGIN DECLARE SECTION;
-  int ngid;
+  int ngid, cnt;
+  char *name, *desc;
   EXEC SQL END DECLARE SECTION;
   unsigned char *p;
   int idx, err;
@@ -310,13 +376,44 @@ int setup_alis(struct query *q, char *argv[], client *cl)
     idx = 0;
   else if (!strcmp(q->shortname, "ulis"))
     idx = 1;
+  name = argv[idx];
+
+  if (q->version == 2)
+    desc = argv[9 + idx];
+  else if (q->version == 3)
+    desc = argv[10 + idx];
+  else if (q->version >= 4)
+    desc = argv[12 + idx];
 
-  for (p = (unsigned char *) argv[idx]; *p; p++)
+  if (idx == 1)
+    {
+      EXEC SQL BEGIN DECLARE SECTION;
+      int lid = *(int *)argv[0];
+      EXEC SQL END DECLARE SECTION;
+
+      if (acl_access_check(lid, cl))
+       return MR_PERM;
+    }
+
+  for (p = (unsigned char *) name; *p; p++)
     {
       if (badlistchars[*p])
        return MR_BAD_CHAR;
     }
 
+  for (p = (unsigned char *) desc; *p; p++)
+    {
+      if (*p == '\n')
+       return MR_BAD_CHAR;
+    }
+
+  /* Check that it doesn't conflict with a pre-existing weirdly-cased
+   * name. */
+  EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
+    WHERE LOWER(name) = :name AND name != :name;
+  if (cnt)
+    return MR_EXISTS;
+
   if (!strcmp(argv[6 + idx], UNIQUE_GID) || atoi(argv[6 + idx]) == -1)
     {
       if (atoi(argv[5 + idx]))
@@ -381,6 +478,11 @@ int setup_dlis(struct query *q, char *argv[], client *cl)
   if (cnt > 0)
     return MR_IN_USE;
 
+  EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
+    WHERE memacl_id = :id AND memacl_type = 'LIST' AND list_id != :id;
+  if (cnt > 0)
+    return MR_IN_USE;
+
   EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
     WHERE acl_id = :id AND acl_type = 'LIST';
   if (cnt > 0)
@@ -400,7 +502,29 @@ int setup_dlis(struct query *q, char *argv[], client *cl)
     WHERE z.xmt_type = 'LIST' AND z.xmt_id = :id
     OR z.sub_type = 'LIST' AND z.sub_id = :id
     OR z.iws_type = 'LIST' AND z.iws_id = :id
-    OR z.iui_type = 'LIST' AND z.iui_id = :id;
+    OR z.iui_type = 'LIST' AND z.iui_id = :id
+    OR z.owner_type = 'LIST' and z.owner_id = :id;
+  if (cnt > 0)
+    return MR_IN_USE;
+
+  EXEC SQL SELECT COUNT(name) INTO :cnt FROM printers
+    WHERE lpc_acl = :id OR ac = :id;
+  if (cnt > 0)
+    return MR_IN_USE;
+
+  EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printservers
+    WHERE owner_type = 'LIST' AND owner_id = :id
+    OR lpc_acl = :id;
+  if (cnt > 0)
+    return MR_IN_USE;
+
+  EXEC SQL SELECT count(name) INTO :cnt FROM containers
+    WHERE acl_id = :id AND acl_type = 'LIST';
+  if (cnt > 0)
+    return MR_IN_USE;
+
+  EXEC SQL SELECT count(name) INTO :cnt FROM containers
+    WHERE memacl_id = :id AND memacl_type = 'LIST';
   if (cnt > 0)
     return MR_IN_USE;
 
@@ -473,7 +597,7 @@ int setup_dshi(struct query *q, char *argv[], client *cl)
  ** Description:
  **   - for type = RVD:
  **       * allow anything
- **   - for type = NFS:
+ **   - for type = NFS/IMAP:
  **        * extract directory prefix from name
  **        * verify mach_id/dir in nfsphys
  **        * verify rwaccess in {r, w, R, W}
@@ -517,7 +641,7 @@ int setup_afil(struct query *q, char *argv[], client *cl)
   if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
     return mr_errcode;
 
-  if (!strcmp(type, "NFS"))
+  if (!strcmp(type, "NFS") || !strcmp(type, "IMAP"))
     return check_nfs(mach_id, name, rwaccess);
 
   return MR_SUCCESS;
@@ -561,7 +685,7 @@ int setup_ufil(struct query *q, char *argv[], client *cl)
   if (dbms_errno)
     return mr_errcode;
 
-  if (!strcmp(type, "NFS"))
+  if (!strcmp(type, "NFS") || !strcmp(type, "IMAP"))
     {
       status = check_nfs(mach_id, name, access);
       EXEC SQL UPDATE quota SET phys_id = :_var_phys_id
@@ -825,11 +949,14 @@ int setup_ahst(struct query *q, char **argv, client *cl)
   EXEC SQL BEGIN DECLARE SECTION;
   char *name, oldname[MACHINE_NAME_SIZE], vendor[MACHINE_VENDOR_SIZE];
   char model[MACHINE_MODEL_SIZE], os[MACHINE_OS_SIZE];
-  int value, id, saddr, mask, high, low, cnt;
+  int value, id, ssaddr, smask, shigh, slow, cnt;
+  unsigned int saddr, mask, high, low;
   EXEC SQL END DECLARE SECTION;
-  int row;
+  int row, idx;
   struct in_addr addr;
 
+  id = *(int *)argv[0];
+
   if (!strcmp(q->shortname, "uhst"))
     {
       row = 1;
@@ -840,83 +967,26 @@ int setup_ahst(struct query *q, char **argv, client *cl)
   else
     row = 0;
 
-  id = *(int *)argv[0];
-
-  /* sanity check name: must start with a letter, contain only
-   * letters, numerals, and hyphen, and not end with a hyphen.
-   */
-  if (row == 0 || strcasecmp(argv[1], oldname))
-    {
-      char *p = argv[row];
-
-      if (!isalpha(*p))
-       return MR_BAD_CHAR;
-      for (; *p; p++)
-       {
-         if ((!isalnum(*p) && *p != '-' && *p != '.') ||
-             (*p == '-' && p[1] == '.'))
-           return MR_BAD_CHAR;
-       }
-      if (*(p - 1) == '-')
-       return MR_BAD_CHAR;
-    }
-
-  /* sanity check host vendor: must start with a letter, contain only
-   * letters, numerals, and hyphen, and end with an alphanumeric.
-   */
-  if (*argv[row + 1] && (row == 0 || strcasecmp(argv[2], vendor)))
-    {
-      char *p = argv[row + 1];
-
-      if (!isalpha(*p))
-       return MR_BAD_CHAR;
-      for (; *p; p++)
-       {
-         if ((!isalnum(*p) && *p != '-' && *p != '.') ||
-             (*p == '-' && p[1] == '.'))
-           return MR_BAD_CHAR;
-       }
-      if (!isalnum(*(p - 1)))
-       return MR_BAD_CHAR;
-    }
-
-  /* sanity check host type: must start with a letter, contain only
-   * letters, numerals, and hyphen, and end with an alphanumeric.
-   */
-  if (*argv[row + 2] && (row == 0 || strcasecmp(argv[3], model)))
-    {
-      char *p = argv[row + 2];
-
-      if (!isalnum(*p))
-       return MR_BAD_CHAR;
-      for (; *p; p++)
-       {
-         if ((!isalnum(*p) && *p != '-' && *p != '.') ||
-             (*p == '-' && p[1] == '.'))
-           return MR_BAD_CHAR;
-       }
-      if (!isalnum(*(p - 1)))
-       return MR_BAD_CHAR;
-    }
-
-  /* sanity check host os: must start with a letter, contain only
-   * letters, numerals, and hyphen, and end with an hyphen alphanumeric.
-   */
-  if (*argv[row + 3] && (row == 0 || strcasecmp(argv[4], os)))
-    {
-      char *p = argv[row + 3];
+  if (q->version < 6)
+    idx = 0;
+  else if (q->version >= 6 && q->version < 8)
+    idx = 1;
+  else
+    idx = 2;
 
-      if (!isalpha(*p))
-       return MR_BAD_CHAR;
-      for (; *p; p++)
-       {
-         if ((!isalnum(*p) && *p != '-' && *p != '.') ||
-             (*p == '-' && p[1] == '.'))
-           return MR_BAD_CHAR;
-       }
-      if (!isalnum(*(p - 1)))
-       return MR_BAD_CHAR;
-    }
+  /* Sanity check name, vendor, model, and os. */
+  if ((row == 0 || strcasecmp(argv[1], oldname)) &&
+      !hostname_check(argv[row]))
+    return MR_BAD_CHAR;
+  if ((row == 0 || strcasecmp(argv[2], vendor)) &&
+      !hostinfo_check(argv[row + 1], 0))
+    return MR_BAD_CHAR;
+  if ((row == 0 || strcasecmp(argv[3], model)) &&
+      !hostinfo_check(argv[row + 2], 1))
+    return MR_BAD_CHAR;
+  if ((row == 0 || strcasecmp(argv[4], os)) &&
+      !hostinfo_check(argv[row + 3], 0))
+    return MR_BAD_CHAR;
 
   /* check for duplicate name */
   name = argv[row];
@@ -928,18 +998,18 @@ int setup_ahst(struct query *q, char **argv, client *cl)
     return MR_EXISTS;
 
   /* check address */
-  if (!strcmp(argv[9 + row], "unassigned"))
+  if (!strcmp(argv[9 + row + idx], "unassigned"))
     value = -1;
-  else if (!strcmp(argv[9 + row], "unique"))
+  else if (!strcmp(argv[9 + row + idx], "unique"))
     {
-      if (*(int *)argv[8 + row] == 0)
+      if (*(int *)argv[8 + row + idx] == 0)
        value = -1;
       else
        value = -2;
     }
   else
     {
-      value = ntohl(inet_addr(argv[9 + row]));
+      value = ntohl(inet_addr(argv[9 + row + idx]));
       if (value == -1)
        return MR_ADDRESS;
     }
@@ -950,11 +1020,15 @@ int setup_ahst(struct query *q, char **argv, client *cl)
       /*
        * an address or unique was specified.
        */
-      id = *(int *)argv[8 + row];
-      EXEC SQL SELECT saddr, mask, high, low INTO :saddr, :mask, :high, :low
-       FROM subnet WHERE snet_id = :id;
+      id = *(int *)argv[8 + row + idx];
+      EXEC SQL SELECT saddr, mask, high, low INTO :ssaddr, :smask,
+       :shigh, :slow FROM subnet WHERE snet_id = :id;
       if (dbms_errno)
        return mr_errcode;
+      saddr = (unsigned) ssaddr;
+      mask = (unsigned) smask;
+      high = (unsigned) shigh;
+      low = (unsigned) slow;
       if (value != -2)
        {
          /*
@@ -970,7 +1044,7 @@ int setup_ahst(struct query *q, char **argv, client *cl)
           * link in an inet_addr() that returns an error for
           * this case.
           */
-         addr.s_addr = inet_addr(argv[9 + row]);
+         addr.s_addr = inet_addr(argv[9 + row + idx]);
          name = inet_ntoa(addr);
          EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
            WHERE address = :name;
@@ -1014,7 +1088,7 @@ int setup_ahst(struct query *q, char **argv, client *cl)
                break;
            }
          if (cnt != 0)
-           return MR_ADDRESS;
+           return MR_NO_ID;
          else
            value = htonl(id);
        }
@@ -1022,13 +1096,13 @@ int setup_ahst(struct query *q, char **argv, client *cl)
        * we have an address in value. Convert it to a string and store it.
        */
       addr.s_addr = htonl(value);
-      strcpy(argv[9 + row], inet_ntoa(addr));
+      strcpy(argv[9 + row + idx], inet_ntoa(addr));
     }
   else
-    strcpy(argv[9 + row], "unassigned");
+    strcpy(argv[9 + row + idx], "unassigned");
 
   /* status checking */
-  value = atoi(argv[7 + row]);
+  value = atoi(argv[7 + row + idx]);
   if (row == 0 && !(value == 1 || value == 0))
     return MR_TYPE;
   if (row == 1)
@@ -1073,16 +1147,8 @@ int setup_ahal(struct query *q, char **argv, client *cl)
   EXEC SQL END DECLARE SECTION;
   char *p;
 
-  p = name = argv[0];
-  if (!isalpha(*p))
-    return MR_BAD_CHAR;
-  for (; *p; p++)
-    {
-      if ((!isalnum(*p) && *p != '-' && *p != '.') ||
-         (*p == '-' && p[1] == '.'))
-       return MR_BAD_CHAR;
-    }
-  if (*(p - 1) == '-')
+  name = argv[0];
+  if (!hostname_check(argv[0]))
     return MR_BAD_CHAR;
 
   EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
@@ -1094,3 +1160,269 @@ int setup_ahal(struct query *q, char **argv, client *cl)
 
   return MR_SUCCESS;
 }
+
+/* setup_uhha(): Check characters in hwaddr, and make sure it's not
+ * a duplicate.
+ */
+int setup_uhha(struct query *q, char **argv, client *cl)
+{
+  EXEC SQL BEGIN DECLARE SECTION;
+  char *hwaddr = argv[1];
+  int count;
+  EXEC SQL END DECLARE SECTION;
+  char *p;
+
+  if (*hwaddr && strcasecmp(hwaddr, "unknown"))
+    {
+      for (p = hwaddr; *p; p++)
+       {
+         if (isupper(*p))
+           *p = tolower(*p);
+         if (!isxdigit(*p))
+           return MR_BAD_CHAR;
+       }
+      if (p != hwaddr + 12)
+       return MR_ADDRESS;
+
+      EXEC SQL SELECT COUNT(hwaddr) INTO :count
+       FROM machine WHERE hwaddr = :hwaddr;
+      if (count)
+       return MR_NOT_UNIQUE;
+    }
+
+  return MR_SUCCESS;
+}
+
+/* setup_aprn(): Make sure name/duplexname don't conflict with
+ * anything. If [ANY] was specified for the spooling host, pick the
+ * least loaded print server that serves this kind of printer.
+ */
+int setup_aprn(struct query *q, char **argv, client *cl)
+{
+  int best = -1, row;
+  char *p;
+  EXEC SQL BEGIN DECLARE SECTION;
+  int mid, usage, count;
+  char types[STRINGS_STRING_SIZE], *hwaddr, *name, *duplexname, *oldname;
+  EXEC SQL END DECLARE SECTION;
+
+  /* Check for aprn or uprn. */
+  if (q->type == APPEND)
+    row = 0;
+  else
+    row = 1;
+
+  name = argv[PRN_NAME + row];
+  duplexname = argv[PRN_DUPLEXNAME + row];
+  oldname = argv[0];
+
+  if (!*name)
+    return MR_BAD_CHAR;
+  else
+    {
+      if (q->type == APPEND)
+       {
+         EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+           WHERE name = :name OR duplexname = :name;
+       }
+      else
+       {
+         EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+           WHERE ( name = :name OR duplexname = :name )
+           AND name != :oldname;
+       }
+      if (dbms_errno)
+       return mr_errcode;
+      if (count)
+       return MR_NOT_UNIQUE;
+    }
+
+  if (*duplexname)
+    {
+      if (q->type == APPEND)
+       {
+         EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+           WHERE name = :duplexname OR duplexname = :duplexname;
+       }
+      else
+       {
+         EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+           WHERE ( name = :duplexname OR duplexname = :duplexname )
+           AND name != :oldname;
+       }
+
+      if (dbms_errno)
+       return mr_errcode;
+      if (count)
+       return MR_NOT_UNIQUE;
+    }
+
+  if (!strcmp(name, duplexname))
+    return MR_NOT_UNIQUE;
+
+  mid = *(int *)argv[PRN_RM + row];
+  if (mid == -1)
+    {
+      EXEC SQL DECLARE csr_rm CURSOR FOR
+       SELECT ps.mach_id, s.string FROM printservers ps, strings s
+       WHERE ps.mach_id IN
+       ( SELECT mach_id FROM serverhosts WHERE service = 'PRINT'
+         AND enable = 1 )
+       AND ps.printer_types = s.string_id;
+      if (dbms_errno)
+       return mr_errcode;
+      EXEC SQL OPEN csr_rm;
+      if (dbms_errno)
+       return mr_errcode;
+
+      while (1)
+       {
+         EXEC SQL FETCH csr_rm INTO :mid, :types;
+         if (sqlca.sqlcode)
+           break;
+
+         for (p = strtok(types, ", "); p; p = strtok(NULL, ", "))
+           {
+             if (!strcasecmp(argv[PRN_TYPE + row], p))
+               {
+                 EXEC SQL SELECT COUNT(name) INTO :usage
+                   FROM printers WHERE rm = :mid;
+
+                 if (best < 0 || usage < best)
+                   {
+                     best = usage;
+                     *(int *)argv[PRN_RM + row] = mid;
+                     break;
+                   }
+               }
+           }
+       }
+      EXEC SQL CLOSE csr_rm;
+      if (dbms_errno)
+       return mr_errcode;
+
+      if (best == -1)
+       return MR_SERVICE;
+    }
+  else
+    {
+      EXEC SQL SELECT mach_id INTO :mid FROM printservers
+       WHERE mach_id = :mid;
+      if (sqlca.sqlcode)
+       return MR_SERVICE;
+    }
+
+  return MR_SUCCESS;
+}
+
+int setup_dpsv(struct query *q, char **argv, client *cl)
+{
+  int id;
+  EXEC SQL BEGIN DECLARE SECTION;
+  int cnt;
+  EXEC SQL END DECLARE SECTION;
+
+  id = *(int *)argv[0];
+
+  EXEC SQL SELECT COUNT(rm) INTO :cnt FROM printers
+    WHERE rm = :id;
+  if (cnt > 0)
+    return MR_IN_USE;
+
+  return MR_SUCCESS;
+}
+
+int setup_dcon(struct query *q, char *argv[], client *cl)
+{
+  EXEC SQL BEGIN DECLARE SECTION;
+  int id, cnt;
+  char containername[CONTAINERS_NAME_SIZE];
+  EXEC SQL END DECLARE SECTION;
+
+  id = *(int *)argv[0];
+  /* check to see if there are machines in this container */
+  EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM mcntmap
+    WHERE cnt_id = :id;
+  if (cnt > 0)
+    return MR_IN_USE;
+
+  /* check to see if there are subcontainers in this container */
+
+  /* get the container name */
+  
+  EXEC SQL SELECT name INTO :containername
+    FROM containers
+    WHERE cnt_id = :id; 
+
+  /* trim off the trailing spaces */
+   strcpy(containername, strtrim(containername));
+
+  EXEC SQL SELECT COUNT(cnt_id) INTO :cnt FROM containers
+    WHERE name LIKE :containername || '/' || '%';
+
+  if (cnt > 0)
+    return MR_IN_USE;
+
+  if (dbms_errno)
+    return mr_errcode;
+  return MR_SUCCESS;
+}
+
+/* hostname_check()
+ * validate the rfc1035/rfc1123-ness of a hostname
+ */
+
+int hostname_check(char *name)
+{
+  char *p;
+  int count;
+
+  /* Sanity check name: must contain only letters, numerals, and
+   * hyphen, and not start or end with a hyphen. Also make sure no
+   * label (the thing the .s seperate) is longer than 63 characters,
+   * or empty.
+   */
+
+  for (p = name, count = 0; *p; p++)
+    {
+      count++;
+      if ((!isalnum(*p) && *p != '-' && *p != '.') ||
+         (*p == '-' && p[1] == '.'))
+       return 0;
+      if (*p == '.')
+       {
+         if (count == 1)
+           return 0;
+         count = 0;
+       }
+      if (count == 64)
+       return 0;
+    }
+  if (*(p - 1) == '-')
+    return 0;
+  return 1;
+}
+
+int hostinfo_check(char *info, int num)
+{
+  char *p;
+
+  if (!*info)
+    return 1;
+
+  /* Sanity check host hostinfo: must start with a letter (or number
+   * if num is true), contain only letters, numerals, and hyphen, and
+   * not end with a hyphen.
+   */
+
+  if (!isalpha(*info) && (!num || !isdigit(*info)))
+    return 0;
+  for (p = info; *p; p++)
+    {
+      if ((!isalnum(*p) && *p != '-' && *p != '.') ||
+         (*p == '-' && p[1] == '.'))
+       return 0;
+    }
+  if (!isalnum(*(p - 1)))
+    return 1;
+}
This page took 0.117443 seconds and 4 git commands to generate.