X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/de940d6f2939d5080a4e6897fcec16abcba3d8f3..9d3d51ad672f0e2d3961581c4675362349a3fe9d:/update/client.c diff --git a/update/client.c b/update/client.c index 3884bf8d..8b8f46c8 100644 --- a/update/client.c +++ b/update/client.c @@ -1,272 +1,122 @@ -/* - * $Source$ - * $Header$ - */ - -#ifndef lint -static char *rcsid_client2_c = "$Header$"; -#endif lint - -/* - * MODULE IDENTIFICATION: - * $Header$ - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. - * For copying and distribution information, please see the file - * . - * DESCRIPTION: - * This code handles the actual distribution of data files - * to servers in the MOIRA server-update program. - * AUTHOR: - * Ken Raeburn (spook@athena.MIT.EDU), - * MIT Project Athena/MIT Information Systems. - * DEFINED VALUES: - * conn - * mr_update_server +/* $Id$ + * + * This code handles the actual distribution of data files + * to servers in the Moira server-update program. + * + * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include - -extern char *malloc(); -extern int errno, dbg; +#include "update.h" -static char buf[BUFSIZ]; -static int code; - -CONNECTION conn; - - -/* - * FUNCTION: - * initialize() - * DESCRIPTION: - * Insures that various libraries have a chance to get - * initialized. - * INPUT: - * OUTPUT: - * RETURN VALUE: - * void - * SIDE EFFECTS: - * Initializes GDB library. - * PROBLEMS: - * - */ -static void -initialize() -{ - static int initialized = 0; +#include +#include +#include +#include - if (!initialized) { - gdb_init(); - initialized++; - } -} +#include +#include +RCSID("$Header$"); -/* - * FUNCTION: - * mr_update_server(service, machine, target_path) - * DESCRIPTION: - * Attempts to perform an update to the named machine - * of the named service. The file DCM_DIR/service.out - * will be sent, then the file SMS_DIR/bin/service.sh, - * the the shell script will be executed. - * INPUT: - * service - * Name of service to be updated; used to find - * the source data file in the MR data directory. - * machine - * target_path - * Location to install the file. - * RETURN VALUE: - * int: - * Error code, or zero if no error was detected - * in the data supplied to this routine. - * SIDE EFFECTS: - * May write information to logs. - * PROBLEMS: - * - */ +extern des_cblock session; +extern char *whoami; -int -mr_update_server(service, machine, target_path, instructions) -char *service; -char *machine; -char *target_path; -char *instructions; +int send_auth(int conn, char *host_name) { -#define ASSERT(condition,stat,amsg) \ - if (!(condition)) { com_err(whoami, stat, amsg); return(stat); } -#define ASSERT2(condition,stat,amsg,arg1) \ - if (!(condition)) { com_err(whoami, stat, amsg, arg1); return(stat); } -#define NONNULL(str) \ - (((str) != (char *)NULL) && (strlen(str) != 0)) - - char *service_address, *service_updated, *pathname; - int on; - - /* some sanity checking of arguments while we build data */ - ASSERT(NONNULL(machine), MR_INTERNAL, " null host name"); - ASSERT(NONNULL(service), MR_INTERNAL, " null service name"); - ASSERT((strlen(machine) + strlen(service) + 2 < BUFSIZ), MR_ARG_TOO_LONG, - " machine and service names"); - sprintf(buf, "%s:%s", machine, service); - service_updated = strsave(buf); - ASSERT(NONNULL(service_updated), MR_NO_MEM, " for service name"); - ASSERT((strlen(machine)+strlen(SERVICE_NAME)+2 < BUFSIZ), MR_ARG_TOO_LONG, - " machine and update service name"); - sprintf(buf, "%s:%s", machine, SERVICE_NAME); - service_address = strsave(buf); - ASSERT(NONNULL(service_address), MR_NO_MEM, " for service address"); - ASSERT(NONNULL(target_path), MR_INTERNAL, " null target pathname"); - ASSERT((strlen(target_path) < MAXPATHLEN), MR_ARG_TOO_LONG, - " target pathname"); - ASSERT2(target_path[0] == '/', MR_NOT_UNIQUE, - " non-absolute pathname supplied \"%s\"", target_path); - sprintf(buf, "%s/%s.out", DCM_DIR, service); - pathname = strsave(buf); - ASSERT(NONNULL(pathname), MR_NO_MEM, " for pathname"); - ASSERT(NONNULL(instructions), MR_NO_MEM, " for instructions"); - ASSERT((strlen(instructions) < MAXPATHLEN), MR_ARG_TOO_LONG, - " instruction pathname"); - - initialize(); - com_err(whoami, 0, "starting update for %s", service_updated); - - /* open connection */ - conn = start_server_connection(service_address, ""); - if (!conn || (connection_status(conn) == CON_STOPPED)) { - com_err(whoami, connection_errno(conn), - " can't connect to update %s", service_address); - return(MR_CANT_CONNECT); + KTEXT_ST ticket_st; + int code, auth_version = 2; + long response; + + code = get_mr_update_ticket(host_name, &ticket_st); + if (code) + return code; + code = send_string(conn, "AUTH_002", 9); + if (code) + return code; + code = recv_int(conn, &response); + if (code) + return code; + if (response) + { + code = send_string(conn, "AUTH_001", 9); + if (code) + return code; + code = recv_int(conn, &response); + if (code) + return code; + if (response) + return response; + auth_version = 1; } - on = 1; - setsockopt(conn->in.fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)); - - /* send authenticators */ - code = send_auth(machine); - if (code) { - com_err(whoami, code, " authorization attempt to %s failed", - service_updated); - goto update_failed; + code = send_string(conn, (char *)ticket_st.dat, ticket_st.length); + if (code) + return code; + code = recv_int(conn, &response); + if (code) + return code; + if (response) + return response; + + if (auth_version == 2) + { + des_key_schedule sched; + C_Block enonce; + char *data; + size_t size; + + code = recv_string(conn, &data, &size); + if (code) + return code; + des_key_sched(session, sched); + des_ecb_encrypt(data, enonce, sched, 1); + free(data); + code = send_string(conn, (char *)enonce, sizeof(enonce)); + if (code) + return code; + code = recv_int(conn, &response); + if (code) + return code; + if (response) + return response; } - - code = send_file(pathname, target_path, 0); - if (code) - goto update_failed; - - /* send instructions for installation */ - strcpy(buf, "/tmp/moira-update.XXXXXX"); - mktemp(buf); - code = send_file(instructions, buf, 0); - if (code) - goto update_failed; - - /* perform installation */ - code = execute(buf); - if (code) { - com_err(whoami, code, " installation of %s failed, code = %d", - service_updated, code); - goto update_failed; - } - - /* finished updates */ - code = MR_SUCCESS; - - update_failed: - send_quit(); - conn = sever_connection(conn); - return(code); -#undef NONNULL -#undef ASSERT + return MR_SUCCESS; } - -static -send_auth(host_name) -char *host_name; +int execute(int conn, char *path) { - KTEXT_ST ticket_st; - KTEXT ticket = &ticket_st; - STRING data; - register int code; - int response; - - code = get_mr_update_ticket(host_name, ticket); - if (code) { - return(code); - } - STRING_DATA(data) = "AUTH_001"; - MAX_STRING_SIZE(data) = 9; - code = send_object(conn, (char *)&data, STRING_T); - if (code) { - return(connection_errno(conn)); - } - code = receive_object(conn, (char *)&response, INTEGER_T); - if (code) { - return(connection_errno(conn)); - } - if (response) { - return(response); - } - STRING_DATA(data) = (char *)ticket->dat; - MAX_STRING_SIZE(data) = ticket->length; - code = send_object(conn, (char *)&data, STRING_T); - if (code) { - return(connection_errno(conn)); - } - code = receive_object(conn, (char *)&response, INTEGER_T); - if (code) { - return(connection_errno(conn)); - } - if (response) { - return(response); - } - return(MR_SUCCESS); + long response; + char *data; + int code; + + data = malloc(10 + strlen(path)); + if (!data) + return ENOMEM; + sprintf(data, "EXEC_002 %s", path); + code = send_string(conn, data, strlen(data) + 1); + free(data); + if (code) + return code; + code = recv_int(conn, &response); + if (code) + return code; + if (response) + return response; + + return MR_SUCCESS; } -static -execute(path) - char *path; +void send_quit(int conn) { - int response; - STRING data; - register int code; - - string_alloc(&data, BUFSIZ); - sprintf(STRING_DATA(data), "EXEC_002 %s", path); - code = send_object(conn, (char *)&data, STRING_T); - if (code) - return(connection_errno(conn)); - code = receive_object(conn, (char *)&response, INTEGER_T); - if (code) - return(connection_errno(conn)); - if (dbg & DBG_TRACE) - com_err(whoami, response, "execute returned %d", response); - if (response) - return(response); - return(MR_SUCCESS); + send_string(conn, "quit", 5); } -send_quit() +void fail(int conn, int err, char *msg) { - STRING str; - if (!conn) - return; - string_alloc(&str, 5); - (void) strcpy(STRING_DATA(str), "quit"); - (void) send_object(conn, (char *)&str, STRING_T); - string_free(&str); + com_err(whoami, err, msg); + return; }