for adding and removing machines from them.
int access_snt(struct query *q, char *argv[], client *cl);
int access_printer(struct query *q, char *argv[], client *cl);
int access_zephyr(struct query *q, char *argv[], client *cl);
+int access_container(struct query *q, char *argv[], client *cl);
/* prototypes from qfollow.pc */
int followup_fix_modby(struct query *q, struct save_queue *sq,
int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
int (*action)(int, char **, void *), void *actarg,
client *cl);
+int followup_gcon(struct query *q, struct save_queue *sq, struct validate *v,
+ int (*action)(int, char **, void *), void *actarg,
+ client *cl);
int followup_ausr(struct query *q, char *argv[], client *cl);
int followup_aqot(struct query *q, char *argv[], client *cl);
int setup_uhha(struct query *q, char *argv[], client *cl);
int setup_aprn(struct query *q, char *argv[], client *cl);
int setup_dpsv(struct query *q, char *argv[], client *cl);
+int setup_dcon(struct query *q, char *argv[], client *cl);
/* prototypes from qsupport.pc */
int set_pobox(struct query *q, char *argv[], client *cl);
int tag_member_of_list(struct query *q, char *argv[], client *cl);
int register_user(struct query *q, char *argv[], client *cl);
int do_user_reservation(struct query *q, char *argv[], client *cl);
+int update_container(struct query *q, char *argv[], client *cl);
int get_ace_use(struct query *q, char **argv, client *cl,
int (*action)(int, char *[], void *), void *actarg);
int get_user_by_reservation(struct query *q, char **argv, client *cl,
int (*action)(int, char *[], void *),
void *actarg);
+int get_machines_of_container(struct query *q, char **argv, client *cl,
+ int (*action)(int, char *[], void *),
+ void *actarg);
+int get_subcontainers_of_container(struct query *q, char **argv, client *cl,
+ int (*action)(int, char *[], void *),
+ void *actarg);
+
/* prototypes from qvalidate.pc */
int validate_fields(struct query *q, char *argv[], struct valobj *vo, int n);
return MR_PERM;
}
+/* access_container - check access for most container operations
+ *
+ * Inputs: argv[0] - cnt_id
+ * q - query name
+ * cl - client name
+ *
+ * - check if that client is a member of the access control list
+ * - OR, if the query is add_machine_to_container or delete_machine_from_container
+ * check if the client is a memeber of the mem_acl list
+ * - if the query is update_container and the container is to be renamed and
+ * it is a top-level container, only priviledged users can do it
+ */
+
+int access_container(struct query *q, char *argv[], client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt_id, acl_id, memacl_id;
+ char acl_type[CONTAINERS_ACL_TYPE_SIZE], memacl_type[CONTAINERS_ACL_TYPE_SIZE];
+ char name[CONTAINERS_NAME_SIZE], *newname;
+ EXEC SQL END DECLARE SECTION;
+ int status;
+
+ cnt_id = *(int *)argv[0];
+
+ /* if amcn or dmcn, container id is the second argument */
+ if (strcmp(q->shortname, "amcn") == 0 || strcmp(q->shortname, "dmcn") == 0)
+ cnt_id = *(int *)argv[1];
+
+ EXEC SQL SELECT acl_id, acl_type, memacl_id, memacl_type, name
+ INTO :acl_id, :acl_type, :memacl_id, :memacl_type, :name
+ FROM containers
+ WHERE cnt_id = :cnt_id;
+
+ if (sqlca.sqlerrd[2] != 1)
+ return MR_INTERNAL;
+
+ /* trim off the trailing spaces */
+ strcpy(name, strtrim(name));
+
+ /* if the query is update_container and the containers is to be renamed
+ * and it is a top-level container, only dbadmin can do it */
+ if (!strcmp(q->shortname, "ucon"))
+ {
+ newname = argv[1];
+ if (strcmp(name, newname) && strchr(name, '/') == NULL)
+ return MR_PERM;
+ }
+
+ /* check for client in access control list and return success right
+ * away if it's there. */
+ if (find_member(acl_type, acl_id, cl))
+ return MR_SUCCESS;
+
+ /* If not amcn, dmcn, we lose. */
+ if (strcmp(q->shortname, "amcn") && strcmp(q->shortname, "dmcn"))
+ return MR_PERM;
+
+ if (find_member(memacl_type, memacl_id, cl))
+ return MR_SUCCESS;
+
+ /* Otherwise fail. */
+ return MR_PERM;
+}
return MR_SUCCESS;
}
}
+
+/* followup_gcon: fix the ace_name, memace_name, and modby */
+
+int followup_gcon(struct query *q, struct save_queue *sq, struct validate *v,
+ int (*action)(int, char *[], void *), void *actarg,
+ client *cl)
+{
+ char **argv;
+ int status;
+
+ while (sq_get_data(sq, &argv))
+ {
+ mr_trim_args(q->vcnt, argv);
+
+ status = fix_ace(argv[4], &argv[5]);
+ if (status && status != MR_NO_MATCH)
+ return status;
+
+ status = fix_ace(argv[6], &argv[7]);
+ if (status && status != MR_NO_MATCH)
+ return status;
+ }
+
+ return followup_fix_modby(q, sq, v, action, actarg, cl);
+}
+
}
EXEC SQL SELECT string_id INTO :j FROM strings WHERE string = :iname;
break;
+ case CONTAINERS_TABLE:
+ EXEC SQL SELECT cnt_id INTO :j FROM containers WHERE name = :iname;
+ break;
default:
return MR_INTERNAL;
}
case STRINGS_TABLE:
EXEC SQL SELECT string INTO :iname FROM strings WHERE string_id = :j;
break;
+ case CONTAINERS_TABLE:
+ EXEC SQL SELECT name INTO :iname FROM containers WHERE cnt_id = :j;
+ break;
default:
return MR_INTERNAL;
}
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;
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
*/
return MR_SUCCESS;
}
+
+int update_container(struct query *q, char *argv[], client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt_id, acl_id, memacl_id, who;
+ char name[CONTAINERS_NAME_SIZE], newchildname[CONTAINERS_NAME_SIZE];
+ char* newname, *entity, *description, *location, *contact, *acl_type, *memacl_type;
+ EXEC SQL END DECLARE SECTION;
+ char* tmpchar;
+ int cnt, childid;
+ char childname[CONTAINERS_NAME_SIZE];
+
+ cnt_id = *(int *)argv[0];
+ newname = argv[1];
+ description = argv[2];
+ location = argv[3];
+ contact = argv[4];
+ acl_type = argv[5];
+ acl_id = *(int *)argv[6];
+ memacl_type = argv[7];
+ memacl_id = *(int *)argv[8];
+ entity = cl->entity;
+ who = cl->client_id;
+
+ EXEC SQL SELECT name INTO :name
+ FROM containers
+ WHERE cnt_id = :cnt_id;
+
+ /* trim off the trailing spaces */
+ strcpy(name, strtrim(name));
+
+ /* if we are renaming the container */
+ if (strcmp(name, newname))
+ {
+ /* make sure that only the name part of the name has been changed */
+ tmpchar = strrchr(name, '/');
+ /* not a top-level name */
+ if (tmpchar)
+ {
+ cnt = tmpchar - name + 1;
+ /* the parent part of the old and new name should be identical */
+ if (strncmp(name, newname, cnt))
+ return MR_NEW_CONTAINER_NAME;
+ }
+ /* top level name, new name should be a top level name too */
+ else
+ {
+ if (strrchr(newname, '/'))
+ return MR_NEW_CONTAINER_NAME;
+ }
+
+ /* update the name for this container */
+ EXEC SQL UPDATE containers
+ SET name = :newname
+ WHERE cnt_id = :cnt_id;
+
+ if (dbms_errno)
+ return mr_errcode;
+
+ /* get names for its child containers */
+ EXEC SQL DECLARE csr_ucon CURSOR FOR
+ SELECT name, cnt_id FROM containers WHERE name LIKE :name || '/' || '%';
+
+ EXEC SQL OPEN csr_ucon;
+ if (dbms_errno)
+ return mr_errcode;
+
+ while (1)
+ {
+ EXEC SQL FETCH csr_ucon INTO :childname, :childid;
+ if (sqlca.sqlcode)
+ break;
+
+ /* concatenate the new parent name with the existing sub-container name
+ * we get the sub-containers new name */
+ tmpchar = childname + strlen(name);
+ strcpy(newchildname, newname);
+ strcat(newchildname, tmpchar);
+
+ /* update the name */
+ EXEC SQL UPDATE containers
+ SET name = :newchildname, modtime = SYSDATE, modby = :who, modwith = :entity
+ WHERE cnt_id = :childid;
+
+ if (sqlca.sqlcode)
+ break;
+ }
+
+ EXEC SQL CLOSE csr_ucon;
+ if (dbms_errno)
+ return mr_errcode;
+ }
+
+ /* update the remaining fields */
+ EXEC SQL UPDATE containers
+ SET description = NVL(:description, CHR(0)), location = NVL(:location, CHR(0)),
+ contact = NVL(:contact, CHR(0)), acl_type = :acl_type, acl_id = :acl_id,
+ memacl_type = :memacl_type, memacl_id = :memacl_id,
+ modtime = SYSDATE, modby = :who, modwith = :entity
+ WHERE cnt_id = :cnt_id;
+
+ if (dbms_errno)
+ return mr_errcode;
+
+ return MR_SUCCESS;
+}
+
+int get_machines_of_container(struct query *q, char *argv[], client *cl,
+ int (*action)(int, char *[], void *), void *actarg)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt_id, isrecursive;
+ char machinename[MACHINE_NAME_SIZE], containername[CONTAINERS_NAME_SIZE];
+ char *qs;
+ EXEC SQL END DECLARE SECTION;
+
+ char querystring[512], tmp [256];
+ char *rargv[2];
+ int found = 0;
+
+ rargv[0] = machinename;
+ rargv[1] = containername;
+
+ cnt_id = *(int *)argv[0];
+ isrecursive = *(int *)argv[1];
+
+ /* get the container name */
+
+ EXEC SQL SELECT name INTO :containername
+ FROM containers
+ WHERE cnt_id = :cnt_id;
+
+ /* trim off the trailing spaces */
+ strcpy(containername, strtrim(containername));
+
+ strcpy(querystring, "SELECT a.name, b.name FROM machine a, containers b, mcntmap c ");
+ strcat(querystring, "WHERE a.mach_id = c.mach_id AND b.cnt_id = c.cnt_id ");
+
+ if (!isrecursive)
+ sprintf(tmp, "AND b.cnt_id = %d ", cnt_id);
+ else
+ sprintf(tmp, "AND (b.cnt_id = %d OR b.name LIKE '%s/%%') ", cnt_id, containername);
+
+ strcat(querystring, tmp);
+ strcat(querystring, "ORDER BY b.name, a.name");
+
+ qs = querystring;
+
+ EXEC SQL PREPARE stmt FROM :qs;
+ if (sqlca.sqlcode)
+ return MR_INTERNAL;
+ EXEC SQL DECLARE curs_gmnm CURSOR FOR stmt;
+ EXEC SQL OPEN curs_gmnm;
+
+ while (1)
+ {
+ EXEC SQL FETCH curs_gmnm INTO :machinename, :containername;
+ if (sqlca.sqlcode)
+ break;
+ (*action)(2, rargv, actarg);
+ found++;
+ }
+
+ EXEC SQL CLOSE curs_gmnm;
+ if (!found)
+ return MR_NO_MATCH;
+ return MR_SUCCESS;
+}
+
+int get_subcontainers_of_container(struct query *q, char *argv[], client *cl,
+ int (*action)(int, char *[], void *), void *actarg)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt_id, isrecursive;
+ char containername[CONTAINERS_NAME_SIZE], subcontainername[CONTAINERS_NAME_SIZE];
+ char *qs;
+ EXEC SQL END DECLARE SECTION;
+
+ char querystring[512], tmp [256];
+ char *rargv[1];
+ int found = 0;
+
+ rargv[0] = subcontainername;
+
+ cnt_id = *(int *)argv[0];
+ isrecursive = *(int *)argv[1];
+
+ /* get the container name */
+
+ EXEC SQL SELECT name INTO :containername
+ FROM containers
+ WHERE cnt_id = :cnt_id;
+
+ /* trim off the trailing spaces */
+ strcpy(containername, strtrim(containername));
+
+ strcpy(querystring, "SELECT name FROM containers ");
+
+ if (!isrecursive)
+ sprintf(tmp, "WHERE name LIKE '%s/%%' and name NOT LIKE '%s/%%/%%' ", containername,
+ containername);
+ else
+ sprintf(tmp, "WHERE name LIKE '%s/%%' ", containername);
+
+ strcat(querystring, tmp);
+ strcat(querystring, "ORDER BY name");
+
+ qs = querystring;
+
+ EXEC SQL PREPARE stmt FROM :qs;
+ if (sqlca.sqlcode)
+ return MR_INTERNAL;
+ EXEC SQL DECLARE curs_gsoc CURSOR FOR stmt;
+ EXEC SQL OPEN curs_gsoc;
+
+ while (1)
+ {
+ EXEC SQL FETCH curs_gsoc INTO :subcontainername;
+ if (sqlca.sqlcode)
+ break;
+ (*action)(1, rargv, actarg);
+ found++;
+ }
+
+ EXEC SQL CLOSE curs_gsoc;
+ if (!found)
+ return MR_NO_MATCH;
+ return MR_SUCCESS;
+}
{V_ID, 0, FILESYS_TABLE, "label", "filsys_id", MR_FILESYS},
};
+static struct valobj VOcon0[] = {
+ {V_ID, 0, CONTAINERS_TABLE, "name", "cnt_id", MR_CONTAINER},
+};
+
static struct valobj VOnum0[] = {
{V_NUM, 0},
};
"sid",
};
-\f
+static char *gcon_fields[] = {
+ "name",
+ "name", "description", "location", "contact",
+ "ace_type", "ace_name", "memace_type", "memace_name", "modtime", "modby", "modwith",
+};
+
+static struct validate gcon_validate = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ followup_gcon,
+};
+
+static char *acon_fields[] = {
+ "name", "description", "location", "contact",
+ "ace_type", "ace_name", "memace_type", "memace_name",
+};
+
+static struct valobj acon_valobj[] = {
+ {V_CHAR, 0, CONTAINERS_TABLE, "name"},
+ {V_LEN, 1, CONTAINERS_TABLE, "description"},
+ {V_CHAR, 2, CONTAINERS_TABLE, "location"},
+ {V_CHAR, 3, CONTAINERS_TABLE, "contact"},
+ {V_TYPE, 4, 0, "ace_type", 0, MR_ACE},
+ {V_TYPEDATA, 5, 0, 0, 0, MR_ACE},
+ {V_TYPE, 6, 0, "ace_type", 0, MR_ACE},
+ {V_TYPEDATA, 7, 0, 0, 0, MR_ACE},
+};
+
+static struct validate acon_validate =
+{
+ acon_valobj,
+ 8,
+ "name",
+ "name = '%s'",
+ 1,
+ "cnt_id",
+ 0,
+ prefetch_value,
+ set_modtime,
+};
+
+static char *ucon_fields[] = {
+ "name",
+ "newname", "description", "location", "contact",
+ "ace_type", "ace_name", "memace_type", "memace_name",
+};
+
+static struct valobj ucon_valobj[] = {
+ {V_ID, 0, CONTAINERS_TABLE, "name", "cnt_id", MR_CONTAINER},
+ {V_RENAME, 1, CONTAINERS_TABLE, "name", "cnt_id", MR_NOT_UNIQUE},
+ {V_LEN, 2, CONTAINERS_TABLE, "description"},
+ {V_CHAR, 3, CONTAINERS_TABLE, "location"},
+ {V_CHAR, 4, CONTAINERS_TABLE, "contact"},
+ {V_TYPE, 5, 0, "ace_type", 0, MR_ACE},
+ {V_TYPEDATA, 6, 0, 0, 0, MR_ACE},
+ {V_TYPE, 7, 0, "ace_type", 0, MR_ACE},
+ {V_TYPEDATA, 8, 0, 0, 0, MR_ACE},
+};
+
+static struct validate ucon_validate =
+{
+ ucon_valobj,
+ 9,
+ 0,
+ 0,
+ 0,
+ 0,
+ access_container,
+ 0,
+ update_container,
+};
+
+static char *dcon_fields[] = {
+ "name",
+};
+
+static struct validate dcon_validate =
+{
+ VOcon0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ setup_dcon,
+ 0,
+};
+
+static char *amcn_fields[] = {
+ "machine", "container",
+};
+
+static struct valobj amcn_valobj[] = /* ADD_MACHINE_TO_CONTAINER */
+{ /* DELETE_MACHINE_FROM_CONTAINER */
+ {V_ID, 0, MACHINE_TABLE, "name", "mach_id", MR_MACHINE},
+ {V_ID, 1, CONTAINERS_TABLE, "name", "cnt_id", MR_CONTAINER},
+};
+
+static struct validate amcn_validate = /* for amtn and dmfn */
+{
+ amcn_valobj,
+ 2,
+ "mach_id",
+ "mach_id = %d and cnt_id = %d",
+ 2,
+ 0,
+ access_container,
+ 0,
+ set_mach_modtime_by_id,
+};
+
+static char *gmoc_fields[] = {
+ "container",
+ "isrecursive",
+ "machine",
+ "container",
+};
+
+static struct validate gmoc_validate =
+{
+ VOcon0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ get_machines_of_container,
+};
+
+static char *gsoc_fields[] = {
+ "container",
+ "isrecursive",
+ "subcontainer",
+};
+
+static struct validate gsoc_validate =
+{
+ VOcon0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ get_subcontainers_of_container,
+};
+
/* Generalized Query Definitions */
/* Multiple versions of the same query MUST be listed in ascending
NULL,
},
+ {
+ /* Q_GCON - GET_CONTAINER, v7 */
+ "get_container",
+ "gcon",
+ 7,
+ RETRIEVE,
+ "c",
+ CONTAINERS_TABLE,
+ "name, description, location, contact, acl_type, acl_id, memacl_type, memacl_id, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM containers",
+ gcon_fields,
+ 11,
+ "name = '%s' AND cnt_id != 0",
+ 1,
+ NULL,
+ &gcon_validate,
+ },
+
+ {
+ /* Q_ACON - ADD_CONTAINER, v7 */ /* uses prefetch_value() for cnt_id */
+ "add_container",
+ "acon",
+ 7,
+ APPEND,
+ "c",
+ CONTAINERS_TABLE,
+ "INTO containers (name, description, location, contact, acl_type, acl_id, memacl_type, memacl_id, cnt_id) VALUES ('%s', NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), '%s', %d, '%s', %d, %s)",
+ acon_fields,
+ 8,
+ 0,
+ 0,
+ NULL,
+ &acon_validate,
+ },
+
+ {
+ /* Q_UCON - UPDATE_CONTAINER, v7 */
+ "update_container",
+ "ucon",
+ 7,
+ UPDATE,
+ 0,
+ CONTAINERS_TABLE,
+ 0,
+ ucon_fields,
+ 8,
+ 0,
+ 1,
+ NULL,
+ &ucon_validate,
+ },
+
+ {
+ /* Q_DCON - DELETE_CONTAINER, v7 */
+ "delete_container",
+ "dcon",
+ 7,
+ DELETE,
+ "c",
+ CONTAINERS_TABLE,
+ NULL,
+ dcon_fields,
+ 0,
+ "cnt_id = %d",
+ 1,
+ NULL,
+ &dcon_validate,
+ },
+
+ {
+ /* Q_AMCN - ADD_MACHINE_TO_CONTAINER, v7 */
+ "add_machine_to_container",
+ "amcn",
+ 7,
+ APPEND,
+ "mcn",
+ MCNTMAP_TABLE,
+ "INTO mcntmap (mach_id, cnt_id) VALUES (%d, %d)",
+ amcn_fields,
+ 2,
+ 0,
+ 0,
+ NULL,
+ &amcn_validate,
+ },
+
+ {
+ /* Q_DMCN - DELETE_MACHINE_FROM_CONTAINER, v7 */
+ "delete_machine_from_container",
+ "dmcn",
+ 7,
+ DELETE,
+ "mcn",
+ MCNTMAP_TABLE,
+ 0,
+ amcn_fields,
+ 0,
+ "mach_id = %d AND cnt_id = %d",
+ 2,
+ NULL,
+ &amcn_validate,
+ },
+
+ {
+ /* Q_GMNM - GET_MACHINE_TO_CONTAINER_MAP, v7 */
+ "get_machine_to_container_map",
+ "gmnm",
+ 7,
+ RETRIEVE,
+ "mcn",
+ MCNTMAP_TABLE,
+ "c.name FROM machine m, containers c, mcntmap mcn",
+ amcn_fields,
+ 1,
+ "m.name = UPPER('%s') AND mcn.cnt_id = c.cnt_id AND mcn.mach_id = m.mach_id",
+ 1,
+ NULL,
+ NULL,
+ },
+
+ {
+ /* Q_GMOC - GET_MACHINES_OF_CONTAINER, v7 */
+ "get_machines_of_container",
+ "gmoc",
+ 7,
+ RETRIEVE,
+ NULL,
+ MCNTMAP_TABLE,
+ NULL,
+ gmoc_fields,
+ 2,
+ NULL,
+ 2,
+ NULL,
+ &gmoc_validate,
+ },
+
+ {
+ /* Q_GSOC - GET_SUBCONTAINERS_OF_CONTAINER, v7 */
+ "get_subcontainers_of_container",
+ "gsoc",
+ 7,
+ RETRIEVE,
+ NULL,
+ CONTAINERS_TABLE,
+ NULL,
+ gsoc_fields,
+ 1,
+ NULL,
+ 2,
+ NULL,
+ &gsoc_validate,
+ },
+
};
int QueryCount = (sizeof(Queries) / sizeof(struct query));