X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/cc1bca5c9d8ce1c4832bcc72abfcf746278bbf03..7c95c11b0d7c14004290e14b92e799ea8bdd1eeb:/server/qsetup.pc?ds=sidebyside diff --git a/server/qsetup.pc b/server/qsetup.pc index 2baf45ec..040d9533 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) { @@ -82,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; } @@ -94,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) @@ -127,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; } @@ -229,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. @@ -287,12 +339,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 +367,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 +378,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 +401,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 +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) @@ -429,7 +502,8 @@ 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; @@ -444,6 +518,16 @@ 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 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; + return MR_SUCCESS; } @@ -868,7 +952,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]; @@ -883,6 +967,13 @@ int setup_ahst(struct query *q, char **argv, client *cl) else row = 0; + if (q->version < 6) + idx = 0; + else if (q->version >= 6 && q->version < 8) + idx = 1; + else + idx = 2; + /* Sanity check name, vendor, model, and os. */ if ((row == 0 || strcasecmp(argv[1], oldname)) && !hostname_check(argv[row])) @@ -907,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; } @@ -929,7 +1020,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) @@ -953,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; @@ -1005,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) @@ -1241,6 +1332,42 @@ int setup_dpsv(struct query *q, char **argv, client *cl) 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 */