X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/34463187fba7a44507665bb75123ee730fdee3d5..5d04c22d15583ec4c446f467ad00376270b0c807:/server/qsupport.pc diff --git a/server/qsupport.pc b/server/qsupport.pc index 63c7e9e1..c18d94d4 100644 --- a/server/qsupport.pc +++ b/server/qsupport.pc @@ -169,7 +169,7 @@ int set_pobox_pop(struct query *q, char **argv, client *cl) * how many different ancestors a member is allowed to have. */ -#define MAXLISTDEPTH 1024 +#define MAXLISTDEPTH 2048 int add_member_to_list(struct query *q, char **argv, client *cl) { @@ -272,6 +272,9 @@ int add_member_to_list(struct query *q, char **argv, client *cl) case 'K': dtypes[dcount] = "KERBEROS"; break; + case 'M': + dtypes[dcount] = "MACHINE"; + break; default: error++; break; @@ -444,6 +447,9 @@ int delete_member_from_list(struct query *q, char **argv, client *cl) case 'K': dtypes[dcount] = "KERBEROS"; break; + case 'M': + dtypes[dcount] = "MACHINE"; + break; default: error++; break; @@ -1036,10 +1042,11 @@ int get_host_by_owner(struct query *q, char *argv[], client *cl, /* get_lists_of_member - given a type and a name, return the name and flags * of all of the lists of the given member. The member_type is one of - * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0], - * and argv[1] will contain the ID of the entity in question. The R* - * types mean to recursively look at every containing list, not just - * when the object in question is a direct member. + * "LIST", "USER", "STRING", "KERBEROS", "MACHINE", "RLIST", "RUSER", + * "RSTRING", "RKERBEROS", or "RMACHINE" in argv[0], and argv[1] will contain + * the ID of the entity in question. The R* types mean to recursively look + * at every containing list, not just when the object in question is a direct + * member. */ int get_lists_of_member(struct query *q, char *argv[], client *cl, @@ -1076,6 +1083,11 @@ int get_lists_of_member(struct query *q, char *argv[], client *cl, atype = "KERBEROS"; direct = 0; } + if (!strcmp(atype, "RMACHINE")) + { + atype = "MACHINE"; + direct = 0; + } rargv[0] = name; rargv[1] = active; @@ -1269,6 +1281,28 @@ int get_members_of_list(struct query *q, char *argv[], client *cl, if (dbms_errno) return mr_errcode; + targv[0] = "MACHINE"; + EXEC SQL DECLARE csr123 CURSOR FOR + SELECT m.name, s.string FROM machine m, imembers im, strings s + WHERE im.list_id = :list_id AND im.member_type = 'MACHINE' + AND im.member_id = m.mach_id AND im.direct > :direct + AND s.string_id = im.tag ORDER BY 1; + if (dbms_errno) + return mr_errcode; + EXEC SQL OPEN csr123; + if (dbms_errno) + return mr_errcode; + while (1) + { + EXEC SQL FETCH csr123 INTO :member_name, :tag; + if (sqlca.sqlcode) + break; + (*action)(targc, targv, actarg); + } + EXEC SQL CLOSE csr123; + if (dbms_errno) + return mr_errcode; + return MR_SUCCESS; } @@ -1440,7 +1474,8 @@ int register_user(struct query *q, char **argv, client *cl) /* find user */ EXEC SQL SELECT users_id, status INTO :users_id, :ostatus FROM users - WHERE unix_uid = :uid AND (status = 0 OR status = 5 OR status = 6); + WHERE unix_uid = :uid AND + (status = 0 OR status = 5 OR status = 6 OR status = 9); if (sqlca.sqlerrd[2] == 0) return MR_NO_MATCH; @@ -1476,13 +1511,9 @@ int register_user(struct query *q, char **argv, client *cl) WHERE label = :login || '.po'; if (dbms_errno) return mr_errcode; - if ((ostatus == 0) || (tmp != users_id)) + if ((ostatus == 0 || ostatus == 9) || (tmp != users_id)) return MR_IN_USE; - EXEC SQL SELECT count(potype) INTO :rowcount FROM users WHERE - login = :login AND potype = 'IMAP'; - if (dbms_errno) - return mr_errcode; - if (rowcount > 0) + else po_exists = 1; } EXEC SQL SELECT COUNT(name) INTO :rowcount FROM alias @@ -1627,11 +1658,12 @@ int register_user(struct query *q, char **argv, client *cl) sprintf(buffer, "u.users_id = %d", users_id); incremental_before(USERS_TABLE, buffer, 0); nstatus = 2; - if (ostatus == 5 || ostatus == 6) + if (ostatus == 5 || ostatus == 6 || ostatus == 9) nstatus = 1; EXEC SQL UPDATE users SET login = :login, status = :nstatus, modtime = SYSDATE, modby = :who, modwith = :entity, - pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity + pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity, + created = SYSDATE, creator = :who WHERE users_id = :users_id; if (dbms_errno) @@ -1646,10 +1678,6 @@ int register_user(struct query *q, char **argv, client *cl) com_err(whoami, 0, "set login name to %s", login); incremental_after(USERS_TABLE, buffer, 0); - /* We've just changed the login name in the DB; recache it in case - the wrong thing got into the cache earlier. */ - cache_entry(login, USERS_TABLE, users_id); - /* create filesystem */ if (set_next_object_id("filsys_id", FILESYS_TABLE, 0)) return MR_NO_ID; @@ -1859,3 +1887,275 @@ int get_user_by_reservation(struct query *q, char **argv, client *cl, 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, flag; + 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]; + char *qual; + int index = 0; + + cnt_id = *(int *)argv[index++]; + newname = argv[index++]; + + if (q->version >= 9) + flag = atoi(argv[index++]); + + description = argv[index++]; + location = argv[index++]; + contact = argv[index++]; + acl_type = argv[index++]; + acl_id = *(int *)argv[index++]; + memacl_type = argv[index++]; + memacl_id = *(int *)argv[index++]; + 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)); + + qual = xmalloc(MAX_FIELD_WIDTH); + sprintf(qual, "name = '%s'", name); + incremental_before(CONTAINERS_TABLE, qual, argv); + + /* 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; + + strcpy(childname, strtrim(childname)); + /* 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 */ + if (q->version >= 9) + { + EXEC SQL UPDATE containers + SET publicflg= :flag, 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; + } + else + { + EXEC SQL UPDATE containers + SET publicflg= :flag, 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; + + sprintf(qual, "name = '%s'", newname); + incremental_after(CONTAINERS_TABLE, qual, argv); + + 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 = atoi(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 LOWER(b.name) LIKE LOWER('%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[2048], tmp [1024]; + char *rargv[1]; + int found = 0; + + rargv[0] = subcontainername; + + cnt_id = *(int *)argv[0]; + isrecursive = atoi(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 LOWER(name) LIKE LOWER('%s/%%') and LOWER(name) NOT LIKE LOWER('%s/%%/%%') ", + containername, containername); + else + sprintf(tmp, "WHERE LOWER(name) LIKE LOWER('%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; +} + +int set_container_list(struct query *q, char *argv[], client *cl) +{ + EXEC SQL BEGIN DECLARE SECTION; + int cnt_id, list_id; + EXEC SQL END DECLARE SECTION; + + cnt_id = *(int *)argv[0]; + list_id = *(int *)argv[1]; + + EXEC SQL UPDATE containers SET list_id = :list_id WHERE cnt_id = :cnt_id; + if (dbms_errno) + return mr_errcode; + + return MR_SUCCESS; +}