X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/6a15bb2408a3465c1118ab46287d3f3ae3a71e2f..b0464d46b56e0321b3fbfc6c443fd93a887a691a:/update/client.c diff --git a/update/client.c b/update/client.c index 709d1f9d..4733e984 100644 --- a/update/client.c +++ b/update/client.c @@ -1,270 +1,164 @@ -/* - * $Source$ - * $Header$ +/* $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 + * . */ -#ifndef lint -static char *rcsid_client2_c = "$Header$"; -#endif lint - -/* - * MODULE IDENTIFICATION: - * $Header$ - * Copyright 1987 MIT Project Athena. - * DESCRIPTION: - * This code handles the actual distribution of data files - * to servers in the SMS server-update program. - * AUTHOR: - * Ken Raeburn (spook@athena.MIT.EDU), - * MIT Project Athena/MIT Information Systems. - * DEFINED VALUES: - * conn - * sms_update_server - */ +#include +#include +#include "update.h" -#include -#include -#include -#include -#include -#include #include -#include -#include -#include - -extern char *malloc(); -extern int errno; +#include +#include +#include -static char buf[BUFSIZ]; -static int code; +#include +#include +#include -CONNECTION conn; +RCSID("$Header$"); +extern des_cblock session; +extern char *whoami; +extern krb5_context context; -/* - * FUNCTION: - * initialize() - * DESCRIPTION: - * Insures that various libraries have a chance to get - * initialized. - * INPUT: - * OUTPUT: - * RETURN VALUE: - * void - * SIDE EFFECTS: - * Initializes GDB library and SMSU error table. - * PROBLEMS: - * - */ -static void -initialize() +int mr_send_krb5_auth(int conn, char *host_name) { - static int initialized = 0; - - if (!initialized) { - gdb_init(); - init_smsU_err_tbl(); - initialized++; + krb5_data auth; + int code; + long response; + + code = get_mr_krb5_update_ticket(host_name, &auth); + if (code) + goto out; + code = send_string(conn, "AUTH_003", 9); + if (code) + goto out; + code = recv_int(conn, &response); + if (code) + goto out; + if (response) + { + /* Talking to a server that doesn't do AUTH_003 */ + krb5_free_data_contents(context, &auth); + return response; + } + code = send_string(conn, (char *)auth.data, auth.length); + if (code) + goto out; + code = recv_int(conn, &response); + if (code) + goto out; + if (response) + { + krb5_free_data_contents(context, &auth); + return response; } -} + return MR_SUCCESS; -/* - * FUNCTION: - * sms_update_server(service, machine, target_path) - * DESCRIPTION: - * Attempts to perform an update to the named machine - * of the named service. The file SMS_DIR/dcm/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 SMS 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: - * - */ + out: + krb5_free_data_contents(context, &auth); + return code; +} -int -sms_update_server(service, machine, target_path, instructions) -char *service; -char *machine; -char *target_path; -char *instructions; +int mr_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; - - /* some sanity checking of arguments while we build data */ - ASSERT(NONNULL(machine), SMS_INTERNAL, " null host name"); - ASSERT(NONNULL(service), SMS_INTERNAL, " null service name"); - ASSERT((strlen(machine) + strlen(service) + 2 < BUFSIZ), SMS_ARG_TOO_LONG, - " machine and service names"); - sprintf(buf, "%s:%s", machine, service); - service_updated = strsave(buf); - ASSERT(NONNULL(service_updated), SMS_NO_MEM, " for service name"); - ASSERT((strlen(machine)+strlen(SERVICE_NAME)+2 < BUFSIZ), SMS_ARG_TOO_LONG, - " machine and update service name"); - sprintf(buf, "%s:%s", machine, SERVICE_NAME); - service_address = strsave(buf); - ASSERT(NONNULL(service_address), SMS_NO_MEM, " for service address"); - ASSERT(NONNULL(target_path), SMS_INTERNAL, " null target pathname"); - ASSERT((strlen(target_path) < MAXPATHLEN), SMS_ARG_TOO_LONG, - " target pathname"); - ASSERT2(target_path[0] == '/', SMS_NOT_UNIQUE, - " non-absolute pathname supplied \"%s\"", target_path); - sprintf(buf, "%s/dcm/%s.out", SMS_DIR, service); - pathname = strsave(buf); - ASSERT(NONNULL(pathname), SMS_NO_MEM, " for pathname"); - ASSERT(NONNULL(instructions), SMS_NO_MEM, " for instructions"); - ASSERT((strlen(instructions) < MAXPATHLEN), SMS_ARG_TOO_LONG, - " instruction pathname"); - - initialize(); - com_err(whoami, 0, "starting update for %s", service_updated); - - /* open connection */ - conn = start_server_connection(service_address, 0); - if (!conn || (connection_status(conn) == CON_STOPPED)) { - com_err(whoami, connection_errno(conn), - " can't connect to update %s", service_address); - return(SMS_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; } - - /* send authenticators */ - code = send_auth(machine); - if (code) { - com_err(whoami, code, " authorization attempt to %s failed", - service_updated); - goto update_failed; - } - - code = send_file(pathname, target_path); - if (code) - goto update_failed; - - /* send instructions for installation */ - strcpy(buf, "/tmp/sms-update.XXXXXX"); - mktemp(buf); - code = send_file(instructions, buf); - 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; + 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; } - - /* finished updates */ - code = SMS_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 mr_execute(int conn, char *path) { - KTEXT_ST ticket_st; - KTEXT ticket = &ticket_st; - STRING data; - register int code; - int response; - - code = get_sms_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(SMS_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 mr_send_quit(int conn) { - union wait 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 (response.w_retcode) { -/**************************************************************** - * The following line is there because the current update servers - * don't return the correct error code when an update fails. Remove - * this line when they are fixed. -mar 7/26/88 - ****************************************************************/ - return(SMS_INTERNAL); -/* return(response.w_retcode); */ - } - return(SMS_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; }