X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/16affa5604e4ae481ad4263aa66fd68c22cf121c..69e2312ebf072dde3acdfc297f4742d028e129ec:/server/qsetup.pc diff --git a/server/qsetup.pc b/server/qsetup.pc index b13e0260..11a4da78 100644 --- a/server/qsetup.pc +++ b/server/qsetup.pc @@ -62,9 +62,18 @@ int setup_ausr(struct query *q, char *argv[], client *cl) else row = 1; - if (strlen(argv[row + 2]) + strlen(argv[row + 3]) + - strlen(argv[row + 4]) + 2 > USERS_FULLNAME_SIZE) - return MR_ARG_TOO_LONG; + 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) { @@ -94,17 +103,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) @@ -127,31 +138,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; } @@ -221,7 +210,7 @@ int setup_dmac(struct query *q, char *argv[], client *cl) 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; @@ -287,12 +276,15 @@ 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, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, /* SPACE - / */ + 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, 1, 0, /* P - _ */ @@ -312,7 +304,7 @@ int setup_alis(struct query *q, char *argv[], client *cl) { EXEC SQL BEGIN DECLARE SECTION; int ngid, cnt; - char *name; + char *name, *desc; EXEC SQL END DECLARE SECTION; unsigned char *p; int idx, err; @@ -323,6 +315,13 @@ int setup_alis(struct query *q, char *argv[], client *cl) 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]; + if (idx == 1) { EXEC SQL BEGIN DECLARE SECTION; @@ -339,6 +338,12 @@ int setup_alis(struct query *q, char *argv[], client *cl) 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 @@ -410,6 +415,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) @@ -429,7 +439,19 @@ 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; @@ -502,7 +524,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} @@ -546,7 +568,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; @@ -590,7 +612,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 @@ -857,7 +879,7 @@ int setup_ahst(struct query *q, char **argv, client *cl) 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]; @@ -872,6 +894,11 @@ int setup_ahst(struct query *q, char **argv, client *cl) else row = 0; + if (q->version < 6) + idx = 0; + else + idx = 1; + /* Sanity check name, vendor, model, and os. */ if ((row == 0 || strcasecmp(argv[1], oldname)) && !hostname_check(argv[row])) @@ -896,18 +923,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; } @@ -918,7 +945,7 @@ int setup_ahst(struct query *q, char **argv, client *cl) /* * an address or unique was specified. */ - id = *(int *)argv[8 + row]; + 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) @@ -942,7 +969,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; @@ -994,13 +1021,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) @@ -1097,42 +1124,76 @@ int setup_uhha(struct query *q, char **argv, client *cl) */ int setup_aprn(struct query *q, char **argv, client *cl) { - int best = -1; + int best = -1, row; char *p; EXEC SQL BEGIN DECLARE SECTION; int mid, usage, count; - char types[SERVERHOSTS_VALUE3_SIZE], *hwaddr, *name; + char types[STRINGS_STRING_SIZE], *hwaddr, *name, *duplexname, *oldname; EXEC SQL END DECLARE SECTION; - name = argv[PRN_NAME]; + /* 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 { - EXEC SQL SELECT COUNT(name) INTO :count FROM printers - WHERE name = :name OR duplexname = :name; + 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; } - name = argv[PRN_DUPLEXNAME]; - if (*name) + if (*duplexname) { - EXEC SQL SELECT COUNT(name) INTO :count FROM printers - WHERE name = :name OR duplexname = :name; + 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 (*(int *)argv[PRN_RM] == -1) + 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 mach_id, value1, value3 FROM serverhosts - WHERE service = 'PRINT'; + 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; @@ -1141,20 +1202,23 @@ int setup_aprn(struct query *q, char **argv, client *cl) while (1) { - EXEC SQL FETCH csr_rm INTO :mid, :usage, :types; + EXEC SQL FETCH csr_rm INTO :mid, :types; if (sqlca.sqlcode) break; - if (best > 0 && usage > best) - continue; - for (p = strtok(types, ", "); p; p = strtok(NULL, ", ")) { - if (!strcasecmp(argv[PRN_TYPE], p)) + if (!strcasecmp(argv[PRN_TYPE + row], p)) { - best = usage; - *(int *)argv[PRN_RM] = mid; - break; + 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; + } } } } @@ -1165,6 +1229,30 @@ int setup_aprn(struct query *q, char **argv, client *cl) 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; }