From 4f6b1a05a97e653caa673e9c95f8be31e3f51599 Mon Sep 17 00:00:00 2001 From: zacheiss Date: Thu, 13 Sep 2001 02:23:23 +0000 Subject: [PATCH] Merge changes from ip-billing-dev branch. --- clients/moira/cluster.c | 137 ++++++++++++--- clients/moira/defs.h | 2 +- clients/moira/f_defs.h | 1 + clients/moira/menus.c | 4 +- clients/stella/stella.c | 135 +++++++++------ db/dbopt.sql | 1 + db/schema.sql | 9 + db/unschema.sql | 1 + gen/Makefile.in | 8 +- gen/ip-billing.gen | 36 ++++ include/moira_site.h | 65 ++++--- lib/mr_et.et | 3 + man/stella.1 | 3 + server/mr_server.h | 3 +- server/qaccess.pc | 45 ++++- server/qfollow.pc | 13 +- server/qsetup.pc | 51 +++++- server/queries2.c | 364 +++++++++++++++++++++++++++++++++++++--- 18 files changed, 727 insertions(+), 154 deletions(-) create mode 100755 gen/ip-billing.gen diff --git a/clients/moira/cluster.c b/clients/moira/cluster.c index 3ef90f8c..b01b70d9 100644 --- a/clients/moira/cluster.c +++ b/clients/moira/cluster.c @@ -83,6 +83,14 @@ static char *states[] = { "Deleted (3)" }; +static char *subnet_states[] = { + "Reserved (0)", + "Billable (1)", + "Private (2)", + "Resnet (3)", + "Infrastructure (4)" +}; + static char *MacState(int state) { static char buf[BUFSIZ]; @@ -95,7 +103,17 @@ static char *MacState(int state) return states[state]; } +static char *SubnetState(int state) +{ + static char buf[BUFSIZ]; + if (state < 0 || state > 4) + { + sprintf(buf, "Unknown (%d)", state); + return buf; + } + return subnet_states[state]; +} /* -------------------- Set Defaults -------------------- */ @@ -115,6 +133,7 @@ static char **SetMachineDefaults(char **info, char *name) info[M_LOC] = strdup(M_DEFAULT_TYPE); info[M_CONTACT] = strdup(M_DEFAULT_TYPE); info[M_BILL_CONTACT] = strdup(M_DEFAULT_TYPE); + info[M_ACCT_NUMBER] = strdup(""); info[M_USE] = strdup("0"); info[M_STAT] = strdup("1"); info[M_SUBNET] = strdup("NONE"); @@ -123,7 +142,7 @@ static char **SetMachineDefaults(char **info, char *name) info[M_OWNER_NAME] = strdup("NONE"); info[M_ACOMMENT] = strdup(""); info[M_OCOMMENT] = strdup(""); - info[16] = info[17] = NULL; + info[17] = info[18] = NULL; return info; } @@ -169,8 +188,11 @@ static char **SetSubnetDefaults(char **info, char *name) { char buf[256]; - info[C_NAME] = strdup(name); + info[SN_NAME] = strdup(name); info[SN_DESC] = strdup(""); + info[SN_STATUS] = strdup("1"); + info[SN_CONTACT] = strdup(DEFAULT_NONE); + info[SN_ACCT_NUMBER] = strdup(""); sprintf(buf, "%ld", ntohl(inet_addr("18.255.0.0"))); info[SN_ADDRESS] = strdup(buf); sprintf(buf, "%ld", ntohl(inet_addr("255.255.0.0"))); @@ -244,7 +266,6 @@ static char *PrintMachInfo(char **info) MacState(atoi(info[M_STAT])), info[M_STAT_CHNG]); Put_message(buf); Put_message(""); - sprintf(buf, "Vendor: %-16s Location: %s", info[M_VENDOR], info[M_LOC]); Put_message(buf); @@ -254,8 +275,8 @@ static char *PrintMachInfo(char **info) sprintf(buf, "OS: %-16s Billing Contact: %s", info[M_OS], info[M_BILL_CONTACT]); Put_message(buf); - Put_message(""); - sprintf(buf, "Opt: %s", info[M_USE]); + sprintf(buf, "Opt: %-16s Account Number: %s", info[M_USE], + info[M_ACCT_NUMBER]); Put_message(buf); Put_message(""); sprintf(buf, "Adm cmt: %s", info[M_ACOMMENT]); @@ -267,6 +288,22 @@ static char *PrintMachInfo(char **info) Put_message(buf); sprintf(buf, MOD_FORMAT, info[M_MODBY], info[M_MODTIME], info[M_MODWITH]); Put_message(buf); + /* Do a get_subnet for the machine's subnet. We need to know if it's + * Private. + */ + args[0] = info[M_SUBNET]; + stat = do_mr_query("get_subnet", 1, args, StoreInfo, &elem); + if (stat) + com_err(program_name, stat, " looking up subnet info"); + if (atoi(((char **)elem->q_data)[2]) == SNET_STATUS_PRIVATE) + { + Put_message(""); + sprintf(buf, "Warning: This host is on a private subnet."); + Put_message(buf); + sprintf(buf, "Billing information shown is superceded by billing information for the subnet."); + Put_message(buf); + } + return info[M_NAME]; } @@ -371,6 +408,12 @@ static char *PrintSubnetInfo(char **info) Put_message(buf); sprintf(buf, " Description: %s", info[SN_DESC]); Put_message(buf); + sprintf(buf, " Status: %s", SubnetState(atoi(info[SN_STATUS]))); + Put_message(buf); + sprintf(buf, " Contact: %s", info[SN_CONTACT]); + Put_message(buf); + sprintf(buf, " Account Number: %s", info[SN_ACCT_NUMBER]); + Put_message(buf); addr.s_addr = htonl(atoi(info[SN_ADDRESS])); mask.s_addr = htonl(atoi(info[SN_MASK])); low.s_addr = htonl(atoi(info[SN_LOW])); @@ -598,6 +641,9 @@ char **AskMCDInfo(char **info, int type, Bool name) if (GetValueFromUser("Machine's billing contact", &info[M_BILL_CONTACT]) == SUB_ERROR) return NULL; + if (GetValueFromUser("Machine's billing account number", + &info[M_ACCT_NUMBER]) == SUB_ERROR) + return NULL; while (1) { int i; @@ -622,59 +668,76 @@ char **AskMCDInfo(char **info, int type, Bool name) if (name) { /* info did not come from SetMachineDefaults(), which does not - * initialize entry 8 (M_STAT_CHNG), therefore we can + * initialize entry 10 (M_STAT_CHNG), therefore we can * free it. */ /* This is an update of an existing machine and the structure * was filled in thru a query to the db which does fill in this * field. */ - free(info[9]); + free(info[10]); } - info[9] = info[M_SUBNET]; - info[10] = info[M_ADDR]; - info[11] = info[M_OWNER_TYPE]; - info[12] = info[M_OWNER_NAME]; - info[13] = info[M_ACOMMENT]; - info[14] = info[M_OCOMMENT]; + info[10] = info[M_SUBNET]; + info[11] = info[M_ADDR]; + info[12] = info[M_OWNER_TYPE]; + info[13] = info[M_OWNER_NAME]; + info[14] = info[M_ACOMMENT]; + info[15] = info[M_OCOMMENT]; if (name) { - if (GetValueFromUser("Machine's network (or 'none')", &info[9]) + if (GetValueFromUser("Machine's network (or 'none')", &info[10]) == SUB_ERROR) return NULL; } if (GetValueFromUser("Machine's address (or 'unassigned' or 'unique')", - &info[10]) == SUB_ERROR) + &info[11]) == SUB_ERROR) return NULL; - if (GetTypeFromUser("Machine's owner type", "ace_type", &info[11]) == + if (GetTypeFromUser("Machine's owner type", "ace_type", &info[12]) == SUB_ERROR) return NULL; - if (strcmp(info[11], "NONE") && - GetValueFromUser("Owner's Name", &info[12]) == SUB_ERROR) + if (strcmp(info[12], "NONE") && + GetValueFromUser("Owner's Name", &info[13]) == SUB_ERROR) return NULL; - if (!strcmp(info[11], "KERBEROS")) + if (!strcmp(info[12], "KERBEROS")) { char *canon; - mrcl_validate_kerberos_member(info[12], &canon); + mrcl_validate_kerberos_member(info[13], &canon); if (mrcl_get_message()) Put_message(mrcl_get_message()); - free(info[12]); - info[12] = canon; + free(info[13]); + info[13] = canon; } - if (GetValueFromUser("Administrative comment", &info[13]) == SUB_ERROR) + if (GetValueFromUser("Administrative comment", &info[14]) == SUB_ERROR) return NULL; - if (GetValueFromUser("Operational comment", &info[14]) == SUB_ERROR) + if (GetValueFromUser("Operational comment", &info[15]) == SUB_ERROR) return NULL; - info[15] = NULL; - FreeAndClear(&info[16], TRUE); + info[16] = NULL; FreeAndClear(&info[17], TRUE); + FreeAndClear(&info[18], TRUE); break; case SUBNET: if (GetValueFromUser("Network description", &info[SN_DESC]) == SUB_ERROR) return NULL; + while (1) + { + int i; + if (GetValueFromUser("Network's status (? for help)", + &info[SN_STATUS]) == SUB_ERROR) + return NULL; + if (isdigit(info[SN_STATUS][0])) + break; + Put_message("Valid status numbers:"); + for (i = 0; i < 5; i++) + Put_message(subnet_states[i]); + } + if (GetValueFromUser("Network's contact", &info[SN_CONTACT]) == SUB_ERROR) + return NULL; + if (GetValueFromUser("Network's billing account number", + &info[SN_ACCT_NUMBER]) == SUB_ERROR) + return NULL; if (GetAddressFromUser("Network address", &info[SN_ADDRESS]) == SUB_ERROR) return NULL; if (GetAddressFromUser("Network mask", &info[SN_MASK]) == SUB_ERROR) @@ -2011,6 +2074,28 @@ struct mqelem *GetMachineByOwner(char *type, char *name) return QueueTop(elem); } +int MachineByAcctNumber(int argc, char **argv) +{ + char *args[0], *account_number; + int status; + struct mqelem *elem = NULL; + + if (GetValueFromUser("Account Number", &account_number) == SUB_ERROR) + return DM_NORMAL; + + args[0] = account_number; + if (status = do_mr_query("get_host_by_account_number", 1, args, StoreInfo, + &elem)) + { + com_err(program_name, status, " in get_host_by_account_number"); + return DM_NORMAL; + } + Loop(QueueTop(elem), (void (*)(char **)) PrintMachInfo); + FreeQueue(elem); + + return DM_NORMAL; +} + int ShowContainerInfo(int argc, char **argv) { struct mqelem *top; diff --git a/clients/moira/defs.h b/clients/moira/defs.h index eb07a5be..ca27e1c3 100644 --- a/clients/moira/defs.h +++ b/clients/moira/defs.h @@ -50,7 +50,7 @@ typedef int Bool; /* What version of the queries are we asking for? */ -#define QUERY_VERSION 7 +#define QUERY_VERSION 8 /* This is unimplemented in the menu stuff, but would be nice. */ diff --git a/clients/moira/f_defs.h b/clients/moira/f_defs.h index c380dfcb..b69ea23c 100644 --- a/clients/moira/f_defs.h +++ b/clients/moira/f_defs.h @@ -47,6 +47,7 @@ int AttachHelp(void); int ShowMachineInfo(int argc, char **argv); int ShowMachineQuery(int argc, char **argv); int MachineByOwner(int argc, char **argv); +int MachineByAcctNumber(int argc, char **argv); int AddMachine(int argc, char **argv); int UpdateMachine(int argc, char **argv); int DeleteMachine(int argc, char **argv); diff --git a/clients/moira/menus.c b/clients/moira/menus.c index 03c5df20..4a566965 100644 --- a/clients/moira/menus.c +++ b/clients/moira/menus.c @@ -510,7 +510,7 @@ Menu machine_menu = { NULLFUNC, NULLFUNC, "Machine Menu", - 8, + 9, { { ShowMachineInfo, NULLMENU, 2, { {"show", "Get machine information"}, @@ -524,6 +524,8 @@ Menu machine_menu = { {"network", "Network (or leave empty to match any): "} } }, SIMPLEFUNC("owner", "Lookup machines by owner", MachineByOwner), + SIMPLEFUNC("acctnumber", "Lookup machines by account number", + MachineByAcctNumber), { AddMachine, NULLMENU, 2, { {"add", "Add a new machine"}, {"network", "Network assignment: "}, diff --git a/clients/stella/stella.c b/clients/stella/stella.c index cff90a5a..1df37978 100644 --- a/clients/stella/stella.c +++ b/clients/stella/stella.c @@ -70,7 +70,8 @@ struct string_list *container_add_queue, *container_remove_queue; char *hostname, *whoami; char *newname, *address, *network, *h_status, *vendor, *model; -char *os, *location, *contact, *billing_contact, *adm_cmt, *op_cmt; +char *os, *location, *contact, *billing_contact, *account_number; +char *adm_cmt, *op_cmt; in_addr_t ipaddress; struct owner_type *owner; @@ -98,7 +99,8 @@ int main(int argc, char **argv) update_alias_flag = verbose = noauth = 0; list_container_flag = update_container_flag = 0; newname = address = network = h_status = vendor = model = NULL; - os = location = contact = billing_contact = adm_cmt = op_cmt = NULL; + os = location = contact = billing_contact = account_number = adm_cmt = NULL; + op_cmt = NULL; owner = NULL; alias_add_queue = alias_remove_queue = NULL; map_add_queue = map_remove_queue = NULL; @@ -217,6 +219,14 @@ int main(int argc, char **argv) } else usage(argv); } + else if (argis("an", "accountnumber")) { + if (arg - argv < argc - 1) { + arg++; + update_flag++; + account_number = *arg; + } else + usage(argv); + } else if (argis("ac", "admcmt")) { if (arg - argv < argc - 1) { arg++; @@ -323,7 +333,7 @@ int main(int argc, char **argv) } /* fire up Moira */ - status = mrcl_connect(server, "stella", 7, !noauth); + status = mrcl_connect(server, "stella", 8, !noauth); if (status == MRCL_AUTH_ERROR) { com_err(whoami, 0, "Try the -noauth flag if you don't " @@ -354,7 +364,7 @@ int main(int argc, char **argv) char *argv[30]; int cnt; - for (cnt = 0; cnt < 16; cnt++) { + for (cnt = 0; cnt < 17; cnt++) { argv[cnt] = ""; } @@ -372,60 +382,62 @@ int main(int argc, char **argv) argv[5] = contact; if (billing_contact) argv[6] = billing_contact; + if (account_number) + argv[7] = account_number; /* The use field always gets set to "0" */ - argv[7] = "0"; + argv[8] = "0"; if (h_status) - argv[8] = h_status; + argv[9] = h_status; else - argv[8] = "1"; + argv[9] = "1"; if (network) - argv[9] = network; + argv[10] = network; if (address) - argv[10] = address; + argv[11] = address; else - argv[10] = "unique"; + argv[11] = "unique"; if (adm_cmt) - argv[13] = adm_cmt; + argv[14] = adm_cmt; if (op_cmt) - argv[14] = op_cmt; + argv[15] = op_cmt; if (owner) { - argv[12] = owner->name; + argv[13] = owner->name; switch (owner->type) { case M_ANY: case M_USER: - argv[11] = "USER"; - status = wrap_mr_query("add_host", 15, argv, NULL, NULL); + argv[12] = "USER"; + status = wrap_mr_query("add_host", 16, argv, NULL, NULL); if (owner->type != M_ANY || status != MR_USER) break; case M_LIST: - argv[11] = "LIST"; - status = wrap_mr_query("add_host", 15, argv, NULL, NULL); + argv[12] = "LIST"; + status = wrap_mr_query("add_host", 16, argv, NULL, NULL); break; case M_KERBEROS: - argv[11] = "KERBEROS"; - status = mrcl_validate_kerberos_member(argv[12], &argv[12]); + argv[12] = "KERBEROS"; + status = mrcl_validate_kerberos_member(argv[13], &argv[13]); if (mrcl_get_message()) mrcl_com_err(whoami); - status = wrap_mr_query("add_host", 15, argv, NULL, NULL); + status = wrap_mr_query("add_host", 16, argv, NULL, NULL); break; case M_NONE: - argv[11] = "NONE"; - status = wrap_mr_query("add_host", 15, argv, NULL, NULL); + argv[12] = "NONE"; + status = wrap_mr_query("add_host", 16, argv, NULL, NULL); break; } } else { - argv[11] = "NONE"; argv[12] = "NONE"; + argv[13] = "NONE"; - status = wrap_mr_query("add_host", 15, argv, NULL, NULL); + status = wrap_mr_query("add_host", 16, argv, NULL, NULL); } if (status) @@ -438,7 +450,7 @@ int main(int argc, char **argv) else if (update_flag) { char *old_argv[30]; - char *argv[16]; + char *argv[17]; char *args[5]; args[0] = canonicalize_hostname(strdup(hostname)); @@ -460,12 +472,13 @@ int main(int argc, char **argv) argv[7] = old_argv[6]; argv[8] = old_argv[7]; argv[9] = old_argv[8]; - argv[10] = old_argv[10]; + argv[10] = old_argv[9]; argv[11] = old_argv[11]; argv[12] = old_argv[12]; argv[13] = old_argv[13]; argv[14] = old_argv[14]; argv[15] = old_argv[15]; + argv[16] = old_argv[16]; argv[0] = canonicalize_hostname(strdup(hostname)); if (newname) @@ -482,50 +495,52 @@ int main(int argc, char **argv) argv[6] = contact; if (billing_contact) argv[7] = billing_contact; + if (account_number) + argv[8] = account_number; if (h_status) - argv[9] = h_status; + argv[10] = h_status; if (network) - argv[10] = network; + argv[11] = network; if (address) - argv[11] = address; + argv[12] = address; if (adm_cmt) - argv[14] = adm_cmt; + argv[15] = adm_cmt; if (op_cmt) - argv[15] = op_cmt; + argv[16] = op_cmt; if (owner) { - argv[13] = owner->name; + argv[14] = owner->name; switch (owner->type) { case M_ANY: case M_USER: - argv[12] = "USER"; - status = wrap_mr_query("update_host", 16, argv, NULL, NULL); + argv[13] = "USER"; + status = wrap_mr_query("update_host", 17, argv, NULL, NULL); if (owner->type != M_ANY || status != MR_USER) break; case M_LIST: - argv[12] = "LIST"; - status = wrap_mr_query("update_host", 16, argv, NULL, NULL); + argv[13] = "LIST"; + status = wrap_mr_query("update_host", 17, argv, NULL, NULL); break; case M_KERBEROS: - argv[12] = "KERBEROS"; - status = mrcl_validate_kerberos_member(argv[13], &argv[13]); + argv[13] = "KERBEROS"; + status = mrcl_validate_kerberos_member(argv[14], &argv[14]); if (mrcl_get_message()) mrcl_com_err(whoami); - status = wrap_mr_query("update_host", 16, argv, NULL, NULL); + status = wrap_mr_query("update_host", 17, argv, NULL, NULL); break; case M_NONE: - argv[12] = "NONE"; - status = wrap_mr_query("update_host", 16, argv, NULL, NULL); + argv[13] = "NONE"; + status = wrap_mr_query("update_host", 17, argv, NULL, NULL); break; } } else - status = wrap_mr_query("update_host", 16, argv, NULL, NULL); + status = wrap_mr_query("update_host", 17, argv, NULL, NULL); if (status) com_err(whoami, status, "while updating host."); @@ -675,6 +690,15 @@ int main(int argc, char **argv) show_host_info_unformatted(argv); else show_host_info(argv); + args[0] = argv[M_SUBNET]; + status = wrap_mr_query("get_subnet", 1, args, store_host_info, argv); + if (status) + com_err(whoami, status, "while getting subnet information"); + if (atoi(argv[SN_STATUS]) == SNET_STATUS_PRIVATE) + { + fprintf(stderr, "\nWarning: This host is on a private subnet.\n"); + fprintf(stderr, "Billing information shown is superceded by billing information for the subnet.\n"); + } } /* list cluster mappings if needed */ @@ -744,18 +768,18 @@ void usage(char **argv) "-c | -contact contact"); fprintf(stderr, USAGE_OPTIONS_FORMAT, "-ac | -admcmt adm_cmt", "-bc | -billingcontact billing_contact"); - fprintf(stderr, USAGE_OPTIONS_FORMAT, "-A | -address address", - "-N | -network network"); - fprintf(stderr, USAGE_OPTIONS_FORMAT, "-am | -addmap cluster", - "-dm | deletemap cluster"); - fprintf(stderr, USAGE_OPTIONS_FORMAT, "-acn | -addcontainer container", - "-dcn | -deletecontainer container"); - fprintf(stderr, USAGE_OPTIONS_FORMAT, "-lm | -listmap", - "-lcn | -listcontainer"); - fprintf(stderr, USAGE_OPTIONS_FORMAT, "-u | -unformatted", - "-v | -verbose"); - fprintf(stderr, USAGE_OPTIONS_FORMAT, "-n | -noauth", - "-db | -database host[:port]"); + fprintf(stderr, USAGE_OPTIONS_FORMAT, "-an | -accountnumber account_number", "-A | -address address"); + fprintf(stderr, USAGE_OPTIONS_FORMAT, "-N | -network network", + "-am | -addmap cluster"); + fprintf(stderr, USAGE_OPTIONS_FORMAT, "-dm | deletemap cluster", + "-acn | -addcontainer container"); + fprintf(stderr, USAGE_OPTIONS_FORMAT, "-dcn | -deletecontainer container", + "-lm | -listmap"); + fprintf(stderr, USAGE_OPTIONS_FORMAT, "-lcn | -listcontainer", + "-u | -unformatted"); + fprintf(stderr, USAGE_OPTIONS_FORMAT, "-v | -verbose", + "-n | -noauth"); + fprintf(stderr, " %-39s\n" , "-db | -database host[:port]"); exit(1); } @@ -848,7 +872,8 @@ void show_host_info(char **argv) argv[M_CONTACT]); printf("OS: %-16s Billing Contact: %s\n", argv[M_OS], argv[M_BILL_CONTACT]); - printf("\nOpt: %s\n", argv[M_USE]); + printf("Opt: %-16s Account Number: %s\n", argv[M_USE], + argv[M_ACCT_NUMBER]); printf("\nAdm cmt: %s\n", argv[M_ACOMMENT]); printf("Op cmt: %s\n", argv[M_OCOMMENT]); printf("\n"); diff --git a/db/dbopt.sql b/db/dbopt.sql index 4c32efae..95afed67 100644 --- a/db/dbopt.sql +++ b/db/dbopt.sql @@ -17,6 +17,7 @@ create index i_mac_loc on machine (location); create index i_mac_snet on machine (snet_id); create index i_mac_hwaddr on machine (hwaddr); create index i_mac_owner on machine (owner_id); +create index i_mac_acctnumber on machine(account_number); create unique index i_hal_name on hostalias (name); create index i_hal_id on hostalias (mach_id); diff --git a/db/schema.sql b/db/schema.sql index 5a5ed49a..25b91ea3 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -64,6 +64,7 @@ create table machine location VARCHAR(16) DEFAULT CHR(0) NOT NULL, contact VARCHAR(32) DEFAULT CHR(0) NOT NULL, billing_contact VARCHAR(32) DEFAULT CHR(0) NOT NULL, + account_number VARCHAR(10) DEFAULT CHR(0) NOT NULL, use INTEGER DEFAULT 0 NOT NULL, status INTEGER DEFAULT 0 NOT NULL, statuschange DATE DEFAULT SYSDATE NOT NULL, @@ -93,6 +94,9 @@ create table subnet name VARCHAR(16) DEFAULT CHR(0) NOT NULL, snet_id INTEGER DEFAULT 0 NOT NULL, description VARCHAR(48) DEFAULT CHR(0) NOT NULL, + status INTEGER DEFAULT 0 NOT NULL, + contact VARCHAR(32) DEFAULT CHR(0) NOT NULL, + account_number VARCHAR(10) DEFAULT CHR(0) NOT NULL, saddr INTEGER DEFAULT 0 NOT NULL, mask INTEGER DEFAULT 0 NOT NULL, low INTEGER DEFAULT 0 NOT NULL, @@ -417,3 +421,8 @@ create table mcntmap mach_id INTEGER DEFAULT 0 NOT NULL, cnt_id INTEGER DEFAULT 0 NOT NULL ); + +create table accountnumbers +( + account_number VARCHAR(10) DEFAULT CHR(0) NOT NULL +); diff --git a/db/unschema.sql b/db/unschema.sql index 5d90174a..3a7bab58 100644 --- a/db/unschema.sql +++ b/db/unschema.sql @@ -30,3 +30,4 @@ drop table usersids; drop table listsids; drop table containers; drop table mcntmap; +drop table accountnumbers; diff --git a/gen/Makefile.in b/gen/Makefile.in index 6fc9663f..7331544c 100644 --- a/gen/Makefile.in +++ b/gen/Makefile.in @@ -42,10 +42,10 @@ TARGET= acl.gen boot.gen dhcp.gen directory.gen hesiod.gen hosts.gen \ mailhub.gen ndb.gen network.gen nfs.gen pobox.gen \ postoffice.gen print.gen warehouse.gen winad.gen www.gen zephyr.gen -SCRIPTS=boot.sh ca.gen dhcp.sh hesiod.sh longjobs.gen longjobs.sh mailhub.sh \ - ndb.sh nfs.sh null.sh postoffice.sh print.sh sapprint.gen sapprint.sh \ - spwatch.gen warehouse.sh www.sh zephyr.sh install_dirs \ - install_quotas zero_quotas +SCRIPTS=boot.sh ca.gen dhcp.sh hesiod.sh ip-billing.gen longjobs.gen \ + longjobs.sh mailhub.sh ndb.sh nfs.sh null.sh postoffice.sh print.sh \ + sapprint.gen sapprint.sh spwatch.gen warehouse.sh www.sh zephyr.sh \ + install_dirs install_quotas zero_quotas .SUFFIXES: .pc .gen diff --git a/gen/ip-billing.gen b/gen/ip-billing.gen new file mode 100755 index 00000000..b7b22e90 --- /dev/null +++ b/gen/ip-billing.gen @@ -0,0 +1,36 @@ +#!/moira/bin/perl -Tw + +# $Id$ +# The following exit codes are defined and MUST BE CONSISTENT with the +# error codes the library uses: +$MR_DBMS_ERR = 47836421; +$MR_OCONFIG = 47836460; + +$outfile = '/moira/dcm/ip-billing.out'; + +use DBI; + +$dbh = DBI->connect("dbi:Oracle:moira", "moira", "moira") + || exit $MR_DBMS_ERR; + +$sth = $dbh->prepare("SELECT m.address, m.location, m.account_number, " . + "m.name, m.contact FROM machine m, subnet s WHERE " . + "m.status = 1 and m.snet_id = s.snet_id " . + "AND s.status = 1") || exit $MR_DBMS_ERR; + +$sth->execute || exit $MR_DBMS_ERR; + +umask 022; +open(OUT, ">$outfile") || exit $MR_OCONFIG; + +while (($address, $location, $accountnumber, $hostname, $contact) = + $sth->fetchrow_array) { + $row= "$address\t$location\t$accountnumber\t$hostname\t$contact\n"; + $row =~ s/\0//g; + print OUT $row; +} + +close(OUT); +$dbh->disconnect; + +exit 0; diff --git a/include/moira_site.h b/include/moira_site.h index e918ecff..142f7b1a 100644 --- a/include/moira_site.h +++ b/include/moira_site.h @@ -165,22 +165,23 @@ #define M_LOC 4 #define M_CONTACT 5 #define M_BILL_CONTACT 6 -#define M_USE 7 -#define M_STAT 8 -#define M_STAT_CHNG 9 -#define M_SUBNET 10 -#define M_ADDR 11 -#define M_OWNER_TYPE 12 -#define M_OWNER_NAME 13 -#define M_ACOMMENT 14 -#define M_OCOMMENT 15 -#define M_CREATED 16 -#define M_CREATOR 17 -#define M_INUSE 18 -#define M_MODTIME 19 -#define M_MODBY 20 -#define M_MODWITH 21 -#define M_END 22 +#define M_ACCT_NUMBER 7 +#define M_USE 8 +#define M_STAT 9 +#define M_STAT_CHNG 10 +#define M_SUBNET 11 +#define M_ADDR 12 +#define M_OWNER_TYPE 13 +#define M_OWNER_NAME 14 +#define M_ACOMMENT 15 +#define M_OCOMMENT 16 +#define M_CREATED 17 +#define M_CREATOR 18 +#define M_INUSE 19 +#define M_MODTIME 20 +#define M_MODBY 21 +#define M_MODWITH 22 +#define M_END 23 /* Machine to Cluster mapping */ @@ -328,17 +329,27 @@ #define SN_NAME 0 #define SN_DESC 1 -#define SN_ADDRESS 2 -#define SN_MASK 3 -#define SN_LOW 4 -#define SN_HIGH 5 -#define SN_PREFIX 6 -#define SN_ACE_TYPE 7 -#define SN_ACE_NAME 8 -#define SN_MODTIME 9 -#define SN_MODBY 10 -#define SN_MODWITH 11 -#define SN_END 12 +#define SN_STATUS 2 +#define SN_CONTACT 3 +#define SN_ACCT_NUMBER 4 +#define SN_ADDRESS 5 +#define SN_MASK 6 +#define SN_LOW 7 +#define SN_HIGH 8 +#define SN_PREFIX 9 +#define SN_ACE_TYPE 10 +#define SN_ACE_NAME 11 +#define SN_MODTIME 12 +#define SN_MODBY 13 +#define SN_MODWITH 14 +#define SN_END 15 + +/* Subnet statuses */ +#define SNET_STATUS_RESERVED 0 +#define SNET_STATUS_BILLABLE 1 +#define SNET_STATUS_PRIVATE 2 +#define SNET_STATUS_RESNET 3 +#define SNET_STATUS_INFRASTRUCTURE 4 /* User Information queries, v3 */ diff --git a/lib/mr_et.et b/lib/mr_et.et index b210fa66..ef4e6306 100644 --- a/lib/mr_et.et +++ b/lib/mr_et.et @@ -228,4 +228,7 @@ ec MR_CONTAINER, ec MR_NEW_CONTAINER_NAME, "The new container name is invalid" +ec MR_ACCOUNT_NUMBER, + "No such account number" + end diff --git a/man/stella.1 b/man/stella.1 index fd86639d..35f160ef 100644 --- a/man/stella.1 +++ b/man/stella.1 @@ -68,6 +68,9 @@ Set the administrative comment for the specified host to \fIadm_cmt\fR. Update the contact information for the given host to \fIcontact\fR. .IP \fB-billingcontact\ \fIcontact\ \fRor\ \fB-bc\ \fIcontact\fR Update the billing contact information for the given host to \fIcontact\fR. +.IP \fB-accountnumber\ \fIaccountnumber\ \fRor\ \fB-an\ \fIaccountnumber\fR +Update the account number information for the given host to +\fIaccountnumber\fR. .IP \fB-status\ \fIstatus\ \fRor\ \fB-S\ \fIstatus\fR Set the status of the specified host to \fIstatus\fR. diff --git a/server/mr_server.h b/server/mr_server.h index 33921e71..1fb83e92 100644 --- a/server/mr_server.h +++ b/server/mr_server.h @@ -49,7 +49,7 @@ extern char krb_realm[REALM_SZ]; /* max length of query argument allowed */ #define ARGLEN 257 /* Used to setup static argv, maximum argc */ -#define QMAXARGS 22 +#define QMAXARGS 25 /* statistics on number of queries by version number */ extern int newqueries; @@ -229,6 +229,7 @@ int setup_dfil(struct query *q, char *argv[], client *cl); int setup_aftg(struct query *q, char *argv[], client *cl); int setup_dnfp(struct query *q, char *argv[], client *cl); int setup_dqot(struct query *q, char *argv[], client *cl); +int setup_asnt(struct query *q, char *argv[], client *cl); int setup_dsnt(struct query *q, char *argv[], client *cl); int setup_ahst(struct query *q, char *argv[], client *cl); int setup_ahal(struct query *q, char *argv[], client *cl); diff --git a/server/qaccess.pc b/server/qaccess.pc index 2f6a4934..9adb3591 100644 --- a/server/qaccess.pc +++ b/server/qaccess.pc @@ -412,16 +412,19 @@ int access_filesys(struct query *q, char *argv[], client *cl) int access_host(struct query *q, char *argv[], client *cl) { EXEC SQL BEGIN DECLARE SECTION; - int mid, sid, id; + int mid, sid, id, subnet_status; char mtype[MACHINE_OWNER_TYPE_SIZE], stype[SUBNET_OWNER_TYPE_SIZE]; + char *account_number; EXEC SQL END DECLARE SECTION; int status, idx; if (q->version < 6) idx = 0; - else + else if (q->version >= 6 && q->version < 8) idx = 1; - + else + idx = 2; + if (q->type == RETRIEVE) { if (strcmp(argv[0], "*") || strcmp(argv[1], "*") || @@ -442,11 +445,24 @@ int access_host(struct query *q, char *argv[], client *cl) return MR_BAD_CHAR; id = *(int *)argv[8 + idx]; - EXEC SQL SELECT s.owner_type, s.owner_id - INTO :stype, :sid FROM subnet s + EXEC SQL SELECT s.owner_type, s.owner_id, s.status + INTO :stype, :sid, :subnet_status FROM subnet s WHERE s.snet_id = :id; mid = 0; + /* Non query owner must provide valid billing information. */ + if (q->version >= 8) + { + if (subnet_status == SNET_STATUS_BILLABLE) + { + account_number = argv[7]; + EXEC SQL SELECT account_number FROM accountnumbers + WHERE account_number = :account_number; + if (sqlca.sqlcode == SQL_NO_MATCH) + return MR_ACCOUNT_NUMBER; + } + } + if (find_member(stype, sid, cl)) return MR_SUCCESS; else @@ -464,14 +480,27 @@ int access_host(struct query *q, char *argv[], client *cl) id = *(int *)argv[0]; EXEC SQL SELECT m.name, m.use, m.contact, m.billing_contact, m.status, m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, m.snet_id, - s.owner_type, s.owner_id INTO :name, :use, :contact, :billing_contact, - :status, :address, :mtype, :mid, :acomment, :ocomment, :snid, :stype, - :sid + s.owner_type, s.owner_id, s.status INTO :name, :use, :contact, + :billing_contact, :status, :address, :mtype, :mid, :acomment, + :ocomment, :snid, :stype, :sid, :subnet_status FROM machine m, subnet s WHERE m.mach_id = :id AND s.snet_id = m.snet_id; if (dbms_errno) return mr_errcode; + /* Non query owner must provide valid billing information. */ + if (q->version >= 8) + { + if (subnet_status == SNET_STATUS_BILLABLE) + { + account_number = argv[8]; + EXEC SQL SELECT account_number FROM accountnumbers + WHERE account_number = :account_number; + if (sqlca.sqlcode == SQL_NO_MATCH) + return MR_ACCOUNT_NUMBER; + } + } + /* non-query-owner cannot change use or ocomment */ if ((use != atoi(argv[7 + idx])) || (ocomment != *(int *)argv[14 + idx])) return MR_PERM; diff --git a/server/qfollow.pc b/server/qfollow.pc index 09a9d1af..4f7d344d 100644 --- a/server/qfollow.pc +++ b/server/qfollow.pc @@ -526,13 +526,18 @@ int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v, client *cl) { char **argv; - int status; + int status, idx; + + if (q->version < 8) + idx = 0; + else + idx = 3; while (sq_get_data(sq, &argv)) { mr_trim_args(q->vcnt, argv); - status = fix_ace(argv[7], &argv[8]); + status = fix_ace(argv[7 + idx], &argv[8 + idx]); if (status && status != MR_NO_MATCH) return status; } @@ -552,8 +557,10 @@ int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v, if (q->version < 6) idx = 0; - else + else if (q->version >= 6 && q->version < 8) idx = 1; + else + idx = 2; while (sq_get_data(sq, &argv)) { diff --git a/server/qsetup.pc b/server/qsetup.pc index ab50d669..4935b387 100644 --- a/server/qsetup.pc +++ b/server/qsetup.pc @@ -229,6 +229,53 @@ int setup_dmac(struct query *q, char *argv[], client *cl) 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) + { + 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. @@ -900,8 +947,10 @@ int setup_ahst(struct query *q, char **argv, client *cl) if (q->version < 6) idx = 0; - else + 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)) && diff --git a/server/queries2.c b/server/queries2.c index 31644d21..efd6ee0c 100644 --- a/server/queries2.c +++ b/server/queries2.c @@ -787,7 +787,7 @@ static char *ghbh2_fields[] = { "inuse", "modtime", "modby", "modwith", }; -static char *ghst_fields[] = { +static char *ghst6_fields[] = { "name", "address", "location", "network", "name", "vendor", "model", "os", "location", "contact", "billing_contact", "use", "status", "status_change", "network", "address", "ace_type", @@ -795,7 +795,7 @@ static char *ghst_fields[] = { "inuse", "modtime", "modby", "modwith", }; -static char *ghbh_fields[] = { +static char *ghbh6_fields[] = { "hwaddr", "name", "vendor", "model", "os", "location", "contact", "billing_contact", "use", "status", "status_change", "network", "address", "ace_type", @@ -803,6 +803,30 @@ static char *ghbh_fields[] = { "inuse", "modtime", "modby", "modwith", }; +static char *ghst_fields[] = { + "name", "address", "location", "network", + "name", "vendor", "model", "os", "location", "contact", "billing_contact", + "account_number", "use", "status", "status_change", "network", "address", + "ace_type", "ace_name", "admin_comment", "ops_comment", "created", "creator", + "inuse", "modtime", "modby", "modwith", +}; + +static char *ghbh_fields[] = { + "hwaddr", + "name", "vendor", "model", "os", "location", "contact", "billing_contact", + "account_number", "use", "status", "status_change", "network", "address", + "ace_type", "ace_name", "admin_comment", "ops_comment", "created", "creator", + "inuse", "modtime", "modby", "modwith", +}; + +static char *ghba_fields[] = { + "account_number", + "name", "vendor", "model", "os", "location", "contact", "billing_contact", + "account_number", "use", "status", "status_change", "network", "address", + "ace_type", "ace_name", "admin_comment", "ops_comment", "created", "creator", + "inuse", "modtime", "modby", "modwith", +}; + static struct validate ghst_validate = { 0, 0, @@ -854,13 +878,13 @@ static struct validate ahst2_validate = { set_uppercase_modtime, }; -static char *ahst_fields[] = { +static char *ahst6_fields[] = { "name", "vendor", "model", "os", "location", "contact", "billing_contact", "use", "status", "subnet", "address", "ace_type", "ace_name", "admin_comment", "ops_comment", }; -static struct valobj ahst_valobj[] = { +static struct valobj ahst6_valobj[] = { {V_CHAR, 0, MACHINE_TABLE, "name"}, {V_CHAR, 1, MACHINE_TABLE, "vendor"}, {V_CHAR, 2, MACHINE_TABLE, "model"}, @@ -877,9 +901,45 @@ static struct valobj ahst_valobj[] = { {V_ID, 14, STRINGS_TABLE, "string", "string_id", MR_NO_MATCH}, }; +static struct validate ahst6_validate = { + ahst6_valobj, + 14, + "name", + "name = UPPER('%s')", + 1, + "mach_id", + access_host, + setup_ahst, + set_uppercase_modtime, +}; + +static char *ahst_fields[] = { + "name", "vendor", "model", "os", "location", "contact", "billing_contact", + "account_number", "use", "status", "subnet", "address", "ace_type", + "ace_name", "admin_comment", "ops_comment", +}; + +static struct valobj ahst_valobj[] = { + {V_CHAR, 0, MACHINE_TABLE, "name"}, + {V_CHAR, 1, MACHINE_TABLE, "vendor"}, + {V_CHAR, 2, MACHINE_TABLE, "model"}, + {V_CHAR, 3, MACHINE_TABLE, "os"}, + {V_CHAR, 4, MACHINE_TABLE, "location"}, + {V_CHAR, 5, MACHINE_TABLE, "contact"}, + {V_CHAR, 6, MACHINE_TABLE, "billing_contact"}, + {V_CHAR, 7, MACHINE_TABLE, "account_number"}, + {V_NUM, 8}, + {V_NUM, 9}, + {V_ID, 10, SUBNET_TABLE, "name", "snet_id", MR_SUBNET}, + {V_TYPE, 12, 0, "ace_type", 0, MR_ACE}, + {V_TYPEDATA, 13, 0, 0, 0, MR_ACE}, + {V_ID, 14, STRINGS_TABLE, "string", "string_id", MR_NO_MATCH}, + {V_ID, 15, STRINGS_TABLE, "string", "string_id", MR_NO_MATCH}, +}; + static struct validate ahst_validate = { ahst_valobj, - 14, + 15, "name", "name = UPPER('%s')", 1, @@ -926,14 +986,14 @@ static struct validate uhst2_validate = { set_modtime_by_id, }; -static char *uhst_fields[] = { +static char *uhst6_fields[] = { "name", "newname", "vendor", "model", "os", "location", "contact", "billing_contact", "use", "status", "subnet", "address", "ace_type", "ace_name", "admin_comment", "ops_comment", }; -static struct valobj uhst_valobj[] = { +static struct valobj uhst6_valobj[] = { {V_CHAR, 0, MACHINE_TABLE, "name"}, {V_ID, 0, MACHINE_TABLE, "name", "mach_id", MR_MACHINE}, {V_RENAME, 1, MACHINE_TABLE, "name", "mach_id", MR_NOT_UNIQUE}, @@ -952,9 +1012,48 @@ static struct valobj uhst_valobj[] = { {V_ID, 15, STRINGS_TABLE, "string", "string_id", MR_NO_MATCH}, }; +static struct validate uhst6_validate = { + uhst6_valobj, + 16, + 0, + 0, + 0, + "mach_id", + access_host, + setup_ahst, + set_modtime_by_id, +}; + +static char *uhst_fields[] = { + "name", + "newname", "vendor", "model", "os", "location", "contact", "billing_contact", + "account_number", "use", "status", "subnet", "address", "ace_type", + "ace_name", "admin_comment", "ops_comment", +}; + +static struct valobj uhst_valobj[] = { + {V_CHAR, 0, MACHINE_TABLE, "name"}, + {V_ID, 0, MACHINE_TABLE, "name", "mach_id", MR_MACHINE}, + {V_RENAME, 1, MACHINE_TABLE, "name", "mach_id", MR_NOT_UNIQUE}, + {V_CHAR, 2, MACHINE_TABLE, "vendor"}, + {V_CHAR, 3, MACHINE_TABLE, "model"}, + {V_CHAR, 4, MACHINE_TABLE, "os"}, + {V_CHAR, 5, MACHINE_TABLE, "location"}, + {V_CHAR, 6, MACHINE_TABLE, "contact"}, + {V_CHAR, 7, MACHINE_TABLE, "billing_contact"}, + {V_CHAR, 8, MACHINE_TABLE, "account_number"}, + {V_NUM, 9}, + {V_NUM, 10}, + {V_ID, 11, SUBNET_TABLE, "name", "snet_id", MR_SUBNET}, + {V_TYPE, 13, 0, "ace_type", 0, MR_ACE}, + {V_TYPEDATA, 14, 0, 0, 0, MR_ACE}, + {V_ID, 15, STRINGS_TABLE, "string", "string_id", MR_NO_MATCH}, + {V_ID, 16, STRINGS_TABLE, "string", "string_id", MR_NO_MATCH}, +}; + static struct validate uhst_validate = { uhst_valobj, - 16, + 17, 0, 0, 0, @@ -1052,12 +1151,19 @@ static struct validate dhal_validate = { 0, }; -static char *gsnt_fields[] = { +static char *gsnt2_fields[] = { "name", "name", "description", "address", "mask", "low", "high", "prefix", "ace_type", "ace_name", "modtime", "modby", "modwith" }; +static char *gsnt_fields[] = { + "name", + "name", "description", "status", "contact", "account_number", "address", + "mask", "low", "high", "prefix", "ace_type", "ace_name", "modtime", + "modby", "modwith" +}; + static struct validate gsnt_validate = { 0, 0, @@ -1070,12 +1176,12 @@ static struct validate gsnt_validate = { followup_gsnt, }; -static char *asnt_fields[] = { +static char *asnt2_fields[] = { "name", "description", "address", "mask", "low", "high", "prefix", "ace_type", "ace_name", }; -static struct valobj asnt_valobj[] = { +static struct valobj asnt2_valobj[] = { {V_CHAR, 0, SUBNET_TABLE, "name"}, {V_LEN, 1, SUBNET_TABLE, "description"}, {V_NUM, 2}, @@ -1087,9 +1193,9 @@ static struct valobj asnt_valobj[] = { {V_TYPEDATA, 8, 0, 0, 0, MR_ACE}, }; -static struct validate asnt_validate = +static struct validate asnt2_validate = { - asnt_valobj, + asnt2_valobj, 9, "name", "name = UPPER('%s')", @@ -1100,13 +1206,46 @@ static struct validate asnt_validate = set_uppercase_modtime, }; -static char *usnt_fields[] = { +static char *asnt_fields[] = { + "name", "description", "status", "contact", "account_number", "address", + "mask", "low", "high", "prefix", "ace_type", "ace_name", +}; + +static struct valobj asnt_valobj[] = { + {V_CHAR, 0, SUBNET_TABLE, "name"}, + {V_LEN, 1, SUBNET_TABLE, "description"}, + {V_NUM, 2}, + {V_CHAR, 3, SUBNET_TABLE, "contact"}, + {V_CHAR, 4, SUBNET_TABLE, "account_number"}, + {V_NUM, 5}, + {V_NUM, 6}, + {V_NUM, 7}, + {V_NUM, 8}, + {V_LEN, 9, SUBNET_TABLE, "prefix"}, + {V_TYPE, 10, 0, "ace_type", 0, MR_ACE}, + {V_TYPEDATA, 11, 0, 0, 0, MR_ACE}, +}; + +static struct validate asnt_validate = +{ + asnt_valobj, + 12, + "name", + "name = UPPER('%s')", + 1, + "snet_id", + 0, + setup_asnt, + set_uppercase_modtime, +}; + +static char *usnt2_fields[] = { "name", "newname", "description", "address", "mask", "low", "high", "prefix", "ace_type", "ace_name", }; -static struct valobj usnt_valobj[] = { +static struct valobj usnt2_valobj[] = { {V_ID, 0, SUBNET_TABLE, "name", "snet_id", MR_NO_MATCH}, {V_RENAME, 1, SUBNET_TABLE, "name", "snet_id", MR_NOT_UNIQUE}, {V_LEN, 2, SUBNET_TABLE, "description"}, @@ -1119,9 +1258,9 @@ static struct valobj usnt_valobj[] = { {V_TYPEDATA, 9, 0, 0, 0, MR_ACE}, }; -static struct validate usnt_validate = +static struct validate usnt2_validate = { - usnt_valobj, + usnt2_valobj, 10, "name", "snet_id = %d", @@ -1132,6 +1271,41 @@ static struct validate usnt_validate = set_modtime_by_id, }; +static char *usnt_fields[] = { + "name", + "newname", "description", "status", "contact", "account_number", "address", + "mask", "low", "high", "prefix", "ace_type", "ace_name", +}; + +static struct valobj usnt_valobj[] = { + {V_ID, 0, SUBNET_TABLE, "name", "snet_id", MR_NO_MATCH}, + {V_RENAME, 1, SUBNET_TABLE, "name", "snet_id", MR_NOT_UNIQUE}, + {V_LEN, 2, SUBNET_TABLE, "description"}, + {V_NUM, 3}, + {V_CHAR, 4, SUBNET_TABLE, "contact"}, + {V_CHAR, 5, SUBNET_TABLE, "account_number"}, + {V_NUM, 6}, + {V_NUM, 7}, + {V_NUM, 8}, + {V_NUM, 9}, + {V_LEN, 10, SUBNET_TABLE, "prefix"}, + {V_TYPE, 11, 0, "ace_type", 0, MR_ACE}, + {V_TYPEDATA, 12, 0, 0, 0, MR_ACE}, +}; + +static struct validate usnt_validate = +{ + usnt_valobj, + 13, + "name", + "snet_id = %d", + 1, + "snet_id", + 0, + setup_asnt, + set_modtime_by_id, +}; + static char *dsnt_fields[] = { "name", }; @@ -4255,7 +4429,7 @@ struct query Queries[] = { "m", MACHINE_TABLE, "m.name, m.vendor, m.model, m.os, m.location, m.contact, m.billing_contact, m.use, m.status, TO_CHAR(m.statuschange, 'DD-mon-YYYY HH24:MI:SS'), s.name, m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, TO_CHAR(m.created, 'DD-mon-YYYY HH24:MI:SS'), m.creator, TO_CHAR(m.inuse, 'DD-mon-YYYY HH24:MI:SS'), TO_CHAR(m.modtime, 'DD-mon-YYYY HH24:MI:SS'), m.modby, m.modwith FROM machine m, subnet s", - ghst_fields, + ghst6_fields, 22, "m.name LIKE UPPER('%s') AND m.address LIKE '%s' AND m.location LIKE UPPER('%s') AND s.name LIKE UPPER('%s') AND m.mach_id != 0 AND s.snet_id = m.snet_id", 4, @@ -4263,6 +4437,23 @@ struct query Queries[] = { &ghst_validate, }, + { + /* Q_GHST - GET_HOST, v8 */ + "get_host", + "ghst", + 8, + RETRIEVE, + "m", + MACHINE_TABLE, + "m.name, m.vendor, m.model, m.os, m.location, m.contact, m.billing_contact, m.account_number, m.use, m.status, TO_CHAR(m.statuschange, 'DD-mon-YYYY HH24:MI:SS'), s.name, m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, TO_CHAR(m.created, 'DD-mon-YYYY HH24:MI:SS'), m.creator, TO_CHAR(m.inuse, 'DD-mon-YYYY HH24:MI:SS'), TO_CHAR(m.modtime, 'DD-mon-YYYY HH24:MI:SS'), m.modby, m.modwith FROM machine m, subnet s", + ghst_fields, + 23, + "m.name LIKE UPPER('%s') AND m.address LIKE '%s' AND m.location LIKE UPPER('%s') AND s.name LIKE UPPER('%s') AND m.mach_id != 0 AND s.snet_id = m.snet_id", + 4, + "m.name", + &ghst_validate, + }, + { /* Q_GHBH - GET_HOST_BY_HWADDR, v2 */ "get_host_by_hwaddr", @@ -4289,7 +4480,7 @@ struct query Queries[] = { "m", MACHINE_TABLE, "m.name, m.vendor, m.model, m.os, m.location, m.contact, m.billing_contact, m.use, m.status, TO_CHAR(m.statuschange, 'DD-mon-YYYY HH24:MI:SS'), s.name, m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, TO_CHAR(m.created, 'DD-mon-YYYY HH24:MI:SS'), m.creator, TO_CHAR(m.inuse, 'DD-mon-YYYY HH24:MI:SS'), TO_CHAR(m.modtime, 'DD-mon-YYYY HH24:MI:SS'), m.modby, m.modwith FROM machine m, subnet s", - ghbh_fields, + ghbh6_fields, 22, "m.hwaddr LIKE LOWER('%s') AND m.mach_id != 0 AND s.snet_id = m.snet_id", 1, @@ -4297,6 +4488,40 @@ struct query Queries[] = { &ghst_validate, }, + { + /* Q_GHBH - GET_HOST_BY_HWADDR, v8 */ + "get_host_by_hwaddr", + "ghbh", + 8, + RETRIEVE, + "m", + MACHINE_TABLE, + "m.name, m.vendor, m.model, m.os, m.location, m.contact, m.billing_contact, m.account_number, m.use, m.status, TO_CHAR(m.statuschange, 'DD-mon-YYYY HH24:MI:SS'), s.name, m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, TO_CHAR(m.created, 'DD-mon-YYYY HH24:MI:SS'), m.creator, TO_CHAR(m.inuse, 'DD-mon-YYYY HH24:MI:SS'), TO_CHAR(m.modtime, 'DD-mon-YYYY HH24:MI:SS'), m.modby, m.modwith FROM machine m, subnet s", + ghbh_fields, + 23, + "m.hwaddr LIKE LOWER('%s') AND m.mach_id != 0 AND s.snet_id = m.snet_id", + 1, + "m.name", + &ghst_validate, + }, + + { + /* Q_GHBA - GET_HOST_BY_ACCOUNT_NUMBER, v8 */ + "get_host_by_account_number", + "ghba", + 8, + RETRIEVE, + "m", + MACHINE_TABLE, + "m.name, m.vendor, m.model, m.os, m.location, m.contact, m.billing_contact, m.account_number, m.use, m.status, TO_CHAR(m.statuschange, 'DD-mon-YYYY HH24:MI:SS'), s.name, m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, TO_CHAR(m.created, 'DD-mon-YYYY HH24:MI:SS'), m.creator, TO_CHAR(m.inuse, 'DD-mon-YYYY HH24:MI:SS'), TO_CHAR(m.modtime, 'DD-mon-YYYY HH24:MI:SS'), m.modby, m.modwith FROM machine m, subnet s", + ghba_fields, + 23, + "m.account_number LIKE '%s' AND m.mach_id != 0 and s.snet_id = m.snet_id", + 1, + "m.name", + &ghst_validate, + }, + { /* Q_GHHA - GET_HOST_HWADDR */ "get_host_hwaddr", @@ -4340,11 +4565,28 @@ struct query Queries[] = { "m", MACHINE_TABLE, "INTO machine (name, vendor, model, os, location, contact, billing_contact, use, status, statuschange, snet_id, address, owner_type, owner_id, acomment, ocomment, created, inuse, mach_id, creator) VALUES (UPPER('%s'), NVL(UPPER('%s'), CHR(0)), NVL(UPPER('%s'), CHR(0)), NVL(UPPER('%s'), CHR(0)), NVL(UPPER('%s'), CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, %s, SYSDATE, %d, '%s', '%s', %d, %d, %d, SYSDATE, SYSDATE, %s, %s)", - ahst_fields, + ahst6_fields, 15, 0, 0, NULL, + &ahst6_validate, + }, + + { + /* Q_AHST - ADD_HOST, v8 */ /* Uses prefetch_value() for mach_id */ + "add_host", + "ahst", + 8, + APPEND, + "m", + MACHINE_TABLE, + "INTO machine (name, vendor, model, os, location, contact, billing_contact, account_number, use, status, statuschange, snet_id, address, owner_type, owner_id, acomment, ocomment, created, inuse, mach_id, creator) VALUES (UPPER('%s'), NVL(UPPER('%s'), CHR(0)), NVL(UPPER('%s'), CHR(0)), NVL(UPPER('%s'), CHR(0)), NVL(UPPER('%s'), CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, %s, SYSDATE, %d, '%s', '%s', %d, %d, %d, SYSDATE, SYSDATE, %s, %s)", + ahst_fields, + 16, + 0, + 0, + NULL, &ahst_validate, }, @@ -4374,11 +4616,28 @@ struct query Queries[] = { "m", MACHINE_TABLE, "machine SET name = NVL(UPPER('%s'), CHR(0)), vendor = NVL(UPPER('%s'), CHR(0)), model = NVL(UPPER('%s'), CHR(0)), os = NVL(UPPER('%s'), CHR(0)), location = NVL(UPPER('%s'), CHR(0)), contact = NVL('%s', CHR(0)), billing_contact = NVL('%s', CHR(0)), use = %s, status = %s, snet_id = %d, address = '%s', owner_type = '%s', owner_id = %d, acomment = %d, ocomment = %d", - uhst_fields, + uhst6_fields, 15, "mach_id = %d", 1, NULL, + &uhst6_validate, + }, + + { + /* Q_UHST - UPDATE_HOST, v8 */ + "update_host", + "uhst", + 8, + UPDATE, + "m", + MACHINE_TABLE, + "machine SET name = NVL(UPPER('%s'), CHR(0)), vendor = NVL(UPPER('%s'), CHR(0)), model = NVL(UPPER('%s'), CHR(0)), os = NVL(UPPER('%s'), CHR(0)), location = NVL(UPPER('%s'), CHR(0)), contact = NVL('%s', CHR(0)), billing_contact = NVL('%s', CHR(0)), account_number = NVL('%s', CHR(0)), use = %s, status = %s, snet_id = %d, address = '%s', owner_type = '%s', owner_id = %d, acomment = %d, ocomment = %d", + uhst_fields, + 16, + "mach_id = %d", + 1, + NULL, &uhst_validate, }, @@ -4485,7 +4744,7 @@ struct query Queries[] = { }, { - /* Q_GSNT - GET_SUBNET */ + /* Q_GSNT - GET_SUBNET, v2 */ "get_subnet", "gsnt", 2, @@ -4493,7 +4752,7 @@ struct query Queries[] = { "s", SUBNET_TABLE, "name, description, saddr, mask, low, high, prefix, owner_type, owner_id, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM subnet", - gsnt_fields, + gsnt2_fields, 12, "name LIKE UPPER('%s')", 1, @@ -4502,7 +4761,24 @@ struct query Queries[] = { }, { - /* Q_ASNT - ADD_SUBNET */ + /* Q_GSNT - GET_SUBNET, v8 */ + "get_subnet", + "gsnt", + 8, + RETRIEVE, + "s", + SUBNET_TABLE, + "name, description, status, contact, account_number, saddr, mask, low, high, prefix, owner_type, owner_id, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM subnet", + gsnt_fields, + 15, + "name LIKE UPPER('%s')", + 1, + "name", + &gsnt_validate, + }, + + { + /* Q_ASNT - ADD_SUBNET, v2 */ "add_subnet", "asnt", 2, @@ -4510,16 +4786,33 @@ struct query Queries[] = { "s", SUBNET_TABLE, "INTO subnet (name, description, saddr, mask, low, high, prefix, owner_type, owner_id, snet_id) VALUES (UPPER('%s'), NVL('%s', CHR(0)), %s, %s, %s, %s, NVL('%s', CHR(0)), '%s', %d, %s)", - asnt_fields, + asnt2_fields, 9, 0, 0, NULL, + &asnt2_validate, + }, + + { + /* Q_ASNT - ADD_SUBNET, v8 */ + "add_subnet", + "asnt", + 8, + APPEND, + "s", + SUBNET_TABLE, + "INTO subnet (name, description, status, contact, account_number, saddr, mask, low, high, prefix, owner_type, owner_id, snet_id) VALUES (UPPER('%s'), NVL('%s', CHR(0)), %s, NVL('%s', CHR(0)), %s, %s, %s, %s, %s, NVL('%s', CHR(0)), '%s', %d, %s)", + asnt_fields, + 12, + 0, + 0, + NULL, &asnt_validate, }, { - /* Q_USNT - UPDATE_SUBNET */ + /* Q_USNT - UPDATE_SUBNET, v2 */ "update_subnet", "usnt", 2, @@ -4527,11 +4820,28 @@ struct query Queries[] = { "s", SUBNET_TABLE, "subnet SET name = UPPER('%s'), description = NVL('%s', CHR(0)), saddr = %s, mask = %s, low = %s, high = %s, prefix = NVL('%s', CHR(0)), owner_type = '%s', owner_id = %d", - usnt_fields, + usnt2_fields, 9, "snet_id = %d", 1, NULL, + &usnt2_validate, + }, + + { + /* Q_USNT - UPDATE_SUBNET, v8 */ + "update_subnet", + "usnt", + 8, + UPDATE, + "s", + SUBNET_TABLE, + "subnet SET name = UPPER('%s'), description = NVL('%s', CHR(0)), status = %s, contact = NVL('%s', CHR(0)), account_number = NVL('%s', CHR(0)), saddr = %s, mask = %s, low = %s, high = %s, prefix = NVL('%s', CHR(0)), owner_type = '%s', owner_id = %d", + usnt_fields, + 12, + "snet_id = %d", + 1, + NULL, &usnt_validate, }, -- 2.45.2