static struct mqelem *GetPrnInfo(char *name, int how) { int stat; struct mqelem *elem = NULL; switch (how) { case BY_NAME: stat = do_mr_query("get_printer", 1, &name, StoreInfo, &elem); if (stat == MR_NO_MATCH) { stat = do_mr_query("get_printer_by_duplexname", 1, &name, StoreInfo, &elem); } break; case BY_ETHERNET: stat = do_mr_query("get_printer_by_ethernet", 1, &name, StoreInfo, &elem); break; case BY_HOSTNAME: name = canonicalize_hostname(strdup(name)); stat = do_mr_query("get_printer_by_hostname", 1, &name, StoreInfo, &elem); free(name); break; case BY_RM: name = canonicalize_hostname(strdup(name)); stat = do_mr_query("get_printer_by_rm", 1, &name, StoreInfo, &elem); free(name); break; case BY_LOCATION: stat = do_mr_query("get_printer_by_location", 1, &name, StoreInfo, &elem); break; case BY_CONTACT: stat = do_mr_query("get_printer_by_contact", 1, &name, StoreInfo, &elem); break; } if (stat) { com_err(program_name, stat, " in GetPrnInfo"); return NULL; } return QueueTop(elem); }
int AddPrintSrv(int argc, char **argv) { char *info[MAX_ARGS_SIZE], **args, *name; int stat; name = canonicalize_hostname(strdup(argv[1])); if (!(stat = do_mr_query("get_print_server", 1, &name, NULL, NULL))) { Put_message ("A print server record for that host already exists."); free(name); return DM_NORMAL; } else if (stat != MR_NO_MATCH) { com_err(program_name, stat, " in AddPrintSrv"); free(name); return DM_NORMAL; } args = AskPrintSrvInfo(SetPrintSrvDefaults(info, name)); free(name); if (!args) { Put_message("Aborted."); return DM_NORMAL; } if ((stat = do_mr_query("add_print_server", CountArgs(args), args, NULL, NULL))) com_err(program_name, stat, " in AddPrintSrv"); FreeInfo(info); return DM_NORMAL; }
int AddACL(int argc, char **argv) { char *info[MAX_ARGS_SIZE], **args; int stat; argv[1] = canonicalize_hostname(strdup(argv[1])); if (!(stat = do_mr_query("get_acl", 2, argv + 1, NULL, NULL))) { Put_message ("An ACL for that host and target already exists."); free(argv[1]); return DM_NORMAL; } else if (stat != MR_NO_MATCH) { com_err(program_name, stat, " in AddACL"); free(argv[1]); return DM_NORMAL; } args = AskACLInfo(SetDefaults(info, argv[1], argv[2])); free(argv[1]); if (!args) { Put_message("Aborted."); return DM_NORMAL; } if ((stat = do_mr_query("add_acl", CountArgs(args), args, NULL, NULL))) com_err(program_name, stat, " in AddACL"); FreeInfo(info); return DM_NORMAL; }
int DeleteNFSService(int argc, char **argv) { int stat; struct mqelem *elem = NULL; char *args[10]; if (!ValidName(argv[1])) return DM_NORMAL; args[0] = canonicalize_hostname(strdup(argv[1])); args[1] = strdup(DEFAULT_DIR); if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR) return DM_NORMAL; switch ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem))) { case MR_NO_MATCH: Put_message("This filsystem does not exist!"); return DM_NORMAL; case MR_SUCCESS: break; default: com_err(program_name, stat, " in DeleteNFSService"); return DM_NORMAL; } free(args[0]); free(args[1]); /* stop memory leaks, in your neighborhood. */ QueryLoop(elem, PrintNFSInfo, RealDeleteNFSService, "Delete the Physical Filesystem on Directory"); FreeQueue(elem); return DM_NORMAL; }
int UpdateNFSService(int argc, char **argv) { int stat; struct mqelem *elem = NULL; char *args[10]; if (!ValidName(argv[1])) return DM_NORMAL; args[0] = canonicalize_hostname(strdup(argv[1])); args[1] = strdup(DEFAULT_DIR); if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR) return DM_NORMAL; if ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem))) { com_err(program_name, stat, " in UpdateNFSService."); return DM_NORMAL; } free(args[0]); free(args[1]); /* stop memory leaks. */ elem = QueueTop(elem); QueryLoop(elem, UpdatePrint, RealUpdateNFSService, "Update NFS Service for"); FreeQueue(elem); return DM_NORMAL; }
int ShowNFSService(int argc, char **argv) { int stat; struct mqelem *elem = NULL; char *args[10]; if (!ValidName(argv[1])) return DM_NORMAL; args[0] = canonicalize_hostname(strdup(argv[1])); args[1] = strdup(DEFAULT_DIR); if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR) return DM_NORMAL; if ((stat = do_mr_query("get_nfsphys", 2, args, StoreInfo, &elem))) com_err(program_name, stat, " in ShowNFSServices."); free(args[0]); free(args[1]); /* prevents memory leaks. */ elem = QueueTop(elem); Loop(elem, (void (*)(char **)) PrintNFSInfo); FreeQueue(elem); return DM_NORMAL; }
int GetFSM(int argc, char **argv) { struct mqelem *top; argv[1] = canonicalize_hostname(strdup(argv[1])); top = GetFSInfo(MACHINE, argv[1]); /* get info. */ Loop(top, (void (*)(char **))PrintFSInfo); FreeQueue(top); /* clean the queue. */ return DM_NORMAL; }
int InterRemoveItemFromLists(int argc, char **argv) { int status; char *type, *name, *args[10], buf[BUFSIZ]; struct mqelem *top, *elem; type = strdup("USER"); if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR) return DM_NORMAL; sprintf(buf, "Name of %s", type); name = strdup(user); if (GetValueFromUser(buf, &name) == SUB_ERROR) return DM_NORMAL; if (!ValidName(name)) return DM_NORMAL; top = elem = GetListInfo(GLOM, type, name); while (elem) { char line[BUFSIZ]; char **info = elem->q_data; sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type, name, info[GLOM_NAME]); switch (YesNoQuitQuestion(line, FALSE)) { case TRUE: Put_message("deleting..."); args[DM_LIST] = info[GLOM_NAME]; args[DM_TYPE] = type; args[DM_MEMBER] = name; if (!strcmp("MACHINE", type)) args[DM_MEMBER] = canonicalize_hostname(strdup(name)); if ((status = do_mr_query("delete_member_from_list", 3, args, NULL, NULL))) { /* should probabally check to delete list. */ com_err(program_name, status, " in delete_member"); } break; case FALSE: break; default: Put_message("Aborting..."); FreeQueue(top); return DM_NORMAL; } elem = elem->q_forw; } FreeQueue(top); return DM_NORMAL; }
int DelPrintSrv(int argc, char **argv) { int stat; char *name; name = canonicalize_hostname(strdup(argv[1])); if ((stat = do_mr_query("delete_print_server", 1, &name, NULL, NULL))) com_err(program_name, stat, " while deleting print server"); free(name); return DM_NORMAL; }
int AddMember(int argc, char **argv) { char *args[10], temp_buf[BUFSIZ], *p; int status; struct mqelem *mailhubs, *elem; if (GetMemberInfo("add", args) == SUB_ERROR) return DM_NORMAL; if (!strcmp(args[LM_TYPE], "STRING")) { status = mrcl_validate_string_member(args[LM_MEMBER]); if (status != MRCL_SUCCESS) Put_message(mrcl_get_message()); if (status == MRCL_REJECT) return DM_NORMAL; } else if (!strcmp(args[LM_TYPE], "KERBEROS")) { char *canon; status = mrcl_validate_kerberos_member(args[LM_MEMBER], &canon); if (mrcl_get_message()) Put_message(mrcl_get_message()); if (status == MRCL_REJECT) return DM_NORMAL; free(args[LM_MEMBER]); args[LM_MEMBER] = canon; } else if (!strcmp(args[LM_TYPE], "MACHINE")) { char *canon; canon = canonicalize_hostname(strdup(args[LM_MEMBER])); free(args[LM_MEMBER]); args[LM_MEMBER] = canon; } if ((status = do_mr_query("add_member_to_list", CountArgs(args), args, NULL, NULL)) != MR_SUCCESS) { if (status == MR_EXISTS) { sprintf(temp_buf, "The %s %s is already a member of LIST %s.", args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]); Put_message(temp_buf); } else com_err(program_name, status, " in AddMember"); } FreeInfo(args); return DM_NORMAL; }
int DeleteMember(int argc, char **argv) { char *args[10]; int status; if (GetMemberInfo("delete", args) == SUB_ERROR) return DM_NORMAL; if (Confirm("Are you sure you want to delete this member?")) { if ((status = do_mr_query("delete_member_from_list", CountArgs(args), args, NULL, NULL))) { if ((status == MR_STRING || status == MR_NO_MATCH) && !strcmp(args[LM_TYPE], "KERBEROS")) { char *canon; mrcl_validate_kerberos_member(args[LM_MEMBER], &canon); if (mrcl_get_message()) { free(args[LM_MEMBER]); args[LM_MEMBER] = canon; if (do_mr_query("delete_member_from_list", CountArgs(args), args, NULL, NULL) == MR_SUCCESS) { Put_message(mrcl_get_message()); status = MR_SUCCESS; } } } else if ((status == MR_MACHINE || status == MR_NO_MATCH) && !strcmp(args[LM_TYPE], "MACHINE")) { char *canon; canon = canonicalize_hostname(args[LM_MEMBER]); args[LM_MEMBER] = canon; if (do_mr_query("delete_member_from_list", CountArgs(args), args, NULL, NULL) == MR_SUCCESS) status = MR_SUCCESS; } } if (status) com_err(program_name, status, " in DeleteMember"); else Put_message("Deletion Completed."); } else Put_message("Deletion has been Aborted."); FreeInfo(args); return DM_NORMAL; }
struct mqelem *GetListInfo(int type, char *name1, char *name2) { char *args[2]; struct mqelem *elem = NULL; int status; switch (type) { case LIST: args[0] = name1; if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem))) { com_err(program_name, status, " in get_list_info"); return NULL; } break; case MEMBERS: args[0] = name1; if ((status = do_mr_query("get_members_of_list", 1, args, StoreInfo, &elem))) { com_err(program_name, status, " in get_members_of_list"); return NULL; } break; case GLOM: args[0] = name1; args[1] = name2; if (!strcmp(name1, "MACHINE")) args[1] = canonicalize_hostname(strdup(name2)); if ((status = do_mr_query("get_lists_of_member", 2, args, StoreInfo, &elem))) { com_err(program_name, status, " in get_list_of_members"); return NULL; } break; case ACE_USE: args[0] = name1; args[1] = name2; if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &elem))) { com_err(program_name, status, " in get_ace_use"); return NULL; } break; } return QueueTop(elem); }
int AddNFSService(int argc, char **argv) { char **add_args, *args[10]; char *info[MAX_ARGS_SIZE]; int stat; args[0] = canonicalize_hostname(strdup(argv[1])); args[1] = strdup(DEFAULT_DIR); if (GetValueFromUser("Directory:", &args[1]) == SUB_ERROR) return DM_NORMAL; if (!ValidName(args[0]) || !ValidName(args[1])) return DM_NORMAL; if (!(stat = do_mr_query("get_nfsphys", 2, args, NULL, NULL))) stat = MR_EXISTS; if (stat != MR_NO_MATCH) { com_err(program_name, stat, " in get_nfsphys."); return DM_NORMAL; } info[NFS_NAME] = strdup(args[0]); info[NFS_DIR] = args[1]; /* already saved. */ info[NFS_DEVICE] = strdup(DEFAULT_DEVICE); info[NFS_STATUS] = strdup(DEFAULT_STATUS); info[NFS_ALLOC] = strdup(DEFAULT_ALLOC); info[NFS_SIZE] = strdup(DEFAULT_SIZE); info[NFS_MODBY] = info[NFS_MODWITH] = info[NFS_MODTIME] = NULL; info[NFS_END] = NULL; if (!(add_args = AskNFSInfo(info))) { Put_message("Aborted."); return DM_NORMAL; } if ((stat = do_mr_query("add_nfsphys", CountArgs(add_args), add_args, NULL, NULL))) com_err(program_name, stat, " in AdsNFSService"); FreeInfo(info); free(args[0]); return DM_NORMAL; }
static struct mqelem *GetACLInfo(char *host, char *target) { int stat; struct mqelem *elem = NULL; char *argv[2]; argv[0] = canonicalize_hostname(strdup(host)); argv[1] = target; stat = do_mr_query("get_acl", 2, argv, StoreInfo, &elem); free(argv[0]); if (stat) { com_err(program_name, stat, " in GetACLInfo"); return NULL; } return QueueTop(elem); }
int ChangePrintSrv(int argc, char **argv) { char *name; struct mqelem *elem = NULL; int stat; name = canonicalize_hostname(strdup(argv[1])); if ((stat = do_mr_query("get_print_server", 1, &name, StoreInfo, &elem))) { free(name); com_err(program_name, stat, " in ChangePrintSrv"); return DM_NORMAL; } free(name); QueryLoop(elem, NullPrint, ChangePrintSrvLoop, "Change the print server"); FreeQueue(elem); return DM_NORMAL; }
int GetPrintSrv(int argc, char **argv) { int stat; struct mqelem *elem = NULL, *top; char *name; name = canonicalize_hostname(strdup(argv[1])); stat = do_mr_query("get_print_server", 1, &name, StoreInfo, &elem); if (stat) { com_err(program_name, stat, " in GetPrintSrv"); return DM_NORMAL; } top = QueueTop(elem); Loop(top, (void (*)(char **)) PrintPrintSrvInfo); FreeQueue(top); /* clean the queue. */ return DM_NORMAL; }
int main(int argc, char **argv) { int status, i, listener; time_t tardy; char *port, *p; extern char *database; struct stat stbuf; struct utsname uts; fd_set readfds, writefds, xreadfds, xwritefds; int nfds, counter = 0; whoami = argv[0]; /* * Error handler init. */ mr_init(); set_com_err_hook(mr_com_err); setvbuf(stderr, NULL, _IOLBF, BUFSIZ); port = strchr(MOIRA_SERVER, ':') + 1; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-db") && i + 1 < argc) { database = argv[i + 1]; i++; } else if (!strcmp(argv[i], "-p") && i + 1 < argc) { port = argv[i + 1]; i++; } else { com_err(whoami, 0, "Usage: moirad [-db database][-p port]"); exit(1); } } status = krb5_init_context(&context); if (status) { com_err(whoami, status, "Initializing krb5 context."); exit(1); } status = krb5_get_default_realm(context, &krb_realm); if (status) { com_err(whoami, status, "Getting default Kerberos realm."); exit(1); } /* * Database initialization. Only init if database should be open. */ if (stat(MOIRA_MOTD_FILE, &stbuf) != 0) { if ((status = mr_open_database())) { com_err(whoami, status, "trying to open database."); exit(1); } sanity_check_database(); } else { dormant = ASLEEP; com_err(whoami, 0, "sleeping, not opening database"); } sanity_check_queries(); /* * Get moira server hostname for authentication */ if (uname(&uts) < 0) { com_err(whoami, errno, "Unable to get local hostname"); exit(1); } host = canonicalize_hostname(xstrdup(uts.nodename)); for (p = host; *p && *p != '.'; p++) { if (isupper(*p)) *p = tolower(*p); } *p = '\0'; /* * Set up client array handler. */ nclients = 0; clientssize = 10; clients = xmalloc(clientssize * sizeof(client *)); mr_setup_signals(); journal = fopen(JOURNAL, "a"); if (!journal) { com_err(whoami, errno, "opening journal file"); exit(1); } /* * Establish template connection. */ listener = mr_listen(port); if (listener == -1) { com_err(whoami, MR_ABORTED, "trying to create listening connection"); exit(1); } FD_ZERO(&xreadfds); FD_ZERO(&xwritefds); FD_SET(listener, &xreadfds); nfds = listener + 1; com_err(whoami, 0, "started (pid %d)", getpid()); com_err(whoami, 0, rcsid); if (dormant != ASLEEP) send_zgram("MOIRA", "server started"); else send_zgram("MOIRA", "server started, but database closed"); /* * Run until shut down. */ while (!takedown) { int i; struct timeval timeout = {60, 0}; /* 1 minute */ /* If we're supposed to go down and we can, do it */ if (((dormant == AWAKE) && (nclients == 0) && (stat(MOIRA_MOTD_FILE, &stbuf) == 0)) || (dormant == SLEEPY)) { mr_close_database(); com_err(whoami, 0, "database closed"); mr_setup_signals(); send_zgram("MOIRA", "database closed"); dormant = ASLEEP; } /* Block until something happens. */ memcpy(&readfds, &xreadfds, sizeof(readfds)); memcpy(&writefds, &xwritefds, sizeof(writefds)); if (select(nfds, &readfds, &writefds, NULL, &timeout) == -1) { if (errno != EINTR) com_err(whoami, errno, "in select"); continue; } if (takedown) break; if (child_exited_abnormally) { critical_alert(whoami, "moirad", "%d: child exits with signal %d status %d", child_pid, child_signal, child_status); child_exited_abnormally = 0; } time(&now); tardy = now - 30 * 60; /* If we're asleep and we should wake up, do it */ if ((dormant == ASLEEP) && (stat(MOIRA_MOTD_FILE, &stbuf) == -1) && (errno == ENOENT)) { mr_open_database(); com_err(whoami, 0, "database open"); mr_setup_signals(); send_zgram("MOIRA", "database open again"); dormant = AWAKE; } /* Handle any new connections */ if (FD_ISSET(listener, &readfds)) { int newconn, addrlen = sizeof(struct sockaddr_in); struct sockaddr_in addr; client *cp; newconn = accept(listener, (struct sockaddr *)&addr, &addrlen); if (newconn == -1) com_err(whoami, errno, "accepting new connection"); else if (newconn > 0) { if (newconn + 1 > nfds) nfds = newconn + 1; FD_SET(newconn, &xreadfds); /* Add a new client to the array */ nclients++; if (nclients > clientssize) { clientssize = 2 * clientssize; clients = xrealloc(clients, clientssize * sizeof(client *)); } clients[nclients - 1] = cp = xmalloc(sizeof(client)); memset(cp, 0, sizeof(client)); cp->con = newconn; cp->id = counter++; cp->last_time_used = now; cp->haddr = addr; cp->tuplessize = 1; cp->tuples = xmalloc(sizeof(mr_params)); memset(cp->tuples, 0, sizeof(mr_params)); cp->state = CL_ACCEPTING; cp->version = 2; cur_client = cp; com_err(whoami, 0, "New connection from %s port %d (now %d client%s)", inet_ntoa(cp->haddr.sin_addr), (int)ntohs(cp->haddr.sin_port), nclients, nclients != 1 ? "s" : ""); } } /* Handle any existing connections. */ for (i = 0; i < nclients; i++) { cur_client = clients[i]; if (FD_ISSET(clients[i]->con, &writefds)) { client_write(clients[i]); if (!clients[i]->ntuples) { FD_CLR(clients[i]->con, &xwritefds); FD_SET(clients[i]->con, &xreadfds); } clients[i]->last_time_used = now; } if (FD_ISSET(clients[i]->con, &readfds)) { if (clients[i]->state == CL_ACCEPTING) { switch(mr_cont_accept(clients[i]->con, &clients[i]->hsbuf, &clients[i]->hslen)) { case -1: break; case 0: clients[i]->state = CL_CLOSING; break; default: clients[i]->state = CL_ACTIVE; clients[i]->hsbuf = NULL; break; } } else { client_read(clients[i]); if (clients[i]->ntuples) { FD_CLR(clients[i]->con, &xreadfds); FD_SET(clients[i]->con, &xwritefds); } clients[i]->last_time_used = now; } } if (clients[i]->last_time_used < tardy) { com_err(whoami, 0, "Shutting down connection due to inactivity"); clients[i]->state = CL_CLOSING; } if (clients[i]->state == CL_CLOSING) { client *old; com_err(whoami, 0, "Closed connection (now %d client%s, " "%d queries)", nclients - 1, nclients != 2 ? "s" : "", newqueries); shutdown(clients[i]->con, 2); close(clients[i]->con); FD_CLR(clients[i]->con, &xreadfds); FD_CLR(clients[i]->con, &xwritefds); free_rtn_tuples(clients[i]); free(clients[i]->tuples); if (clients[i]->hsbuf) free(clients[i]->hsbuf); old = clients[i]; clients[i] = clients[--nclients]; free(old); } cur_client = NULL; if (takedown) break; } } com_err(whoami, 0, "%s", takedown); if (dormant != ASLEEP) mr_close_database(); send_zgram("MOIRA", takedown); return 0; }