]> andersk Git - moira.git/blob - update/client.c
Remove code from update_test that was duplicated in client.c
[moira.git] / update / client.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5
6 #ifndef lint
7 static char *rcsid_client2_c = "$Header$";
8 #endif  lint
9
10 /*
11  * MODULE IDENTIFICATION:
12  *      $Header$
13  *      Copyright 1987, 1988 by the Massachusetts Institute of Technology.
14  *      For copying and distribution information, please see the file
15  *      <mit-copyright.h>.
16  * DESCRIPTION:
17  *      This code handles the actual distribution of data files
18  *      to servers in the MOIRA server-update program.
19  * AUTHOR:
20  *      Ken Raeburn (spook@athena.MIT.EDU),
21  *              MIT Project Athena/MIT Information Systems.
22  * DEFINED VALUES:
23  *      conn
24  *      mr_update_server
25  */
26
27 #include <mit-copyright.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <gdb.h>
32 #include <sys/param.h>
33 #include <sys/wait.h>
34 #include <sys/socket.h>
35 #include <update.h>
36 #include <errno.h>
37 #include <dcm.h>
38 #include <moira.h>
39 #include <moira_site.h>
40 #include <krb.h>
41
42 extern int errno, dbg;
43 extern C_Block session;
44
45 static char buf[BUFSIZ];
46 static int code;
47
48 CONNECTION conn;
49
50
51 /*
52  * FUNCTION:
53  *      initialize()
54  * DESCRIPTION:
55  *      Insures that various libraries have a chance to get
56  *      initialized.
57  * INPUT:
58  * OUTPUT:
59  * RETURN VALUE:
60  *      void
61  * SIDE EFFECTS:
62  *      Initializes GDB library.
63  * PROBLEMS:
64  *
65  */
66 static void
67 initialize()
68 {
69     static int initialized = 0;
70
71     if (!initialized) {
72         gdb_init();
73         initialized++;
74     }
75 }
76
77
78 /*
79  * FUNCTION:
80  *      mr_update_server(service, machine, target_path)
81  * DESCRIPTION:
82  *      Attempts to perform an update to the named machine
83  *      of the named service.  The file DCM_DIR/service.out
84  *      will be sent, then the file SMS_DIR/bin/service.sh,
85  *      the the shell script will be executed.
86  * INPUT:
87  *      service
88  *              Name of service to be updated; used to find
89  *              the source data file in the MR data directory.
90  *      machine
91  *      target_path
92  *              Location to install the file.
93  * RETURN VALUE:
94  *      int:
95  *              Error code, or zero if no error was detected
96  *              in the data supplied to this routine.
97  * SIDE EFFECTS:
98  *      May write information to logs.
99  * PROBLEMS:
100  *
101  */
102
103 int
104 mr_update_server(service, machine, target_path, instructions)
105 char *service;
106 char *machine;
107 char *target_path;
108 char *instructions;
109 {
110 #define ASSERT(condition,stat,amsg) \
111     if (!(condition)) { com_err(whoami, stat, amsg); return(stat); }
112 #define ASSERT2(condition,stat,amsg,arg1) \
113     if (!(condition)) { com_err(whoami, stat, amsg, arg1); return(stat); }
114 #define NONNULL(str) \
115     (((str) != (char *)NULL) && (strlen(str) != 0))
116
117     char *service_address, *service_updated, *pathname;
118     int on;
119     
120     /* some sanity checking of arguments while we build data */
121     ASSERT(NONNULL(machine), MR_INTERNAL, " null host name");
122     ASSERT(NONNULL(service), MR_INTERNAL, " null service name");
123     ASSERT((strlen(machine) + strlen(service) + 2 < BUFSIZ), MR_ARG_TOO_LONG,
124            " machine and service names");
125     sprintf(buf, "%s:%s", machine, service);
126     service_updated = strsave(buf);
127     ASSERT(NONNULL(service_updated), MR_NO_MEM, " for service name");
128     ASSERT((strlen(machine)+strlen(SERVICE_NAME)+2 < BUFSIZ), MR_ARG_TOO_LONG,
129            " machine and update service name");
130     sprintf(buf, "%s:%s", machine, SERVICE_NAME);
131     service_address = strsave(buf);
132     ASSERT(NONNULL(service_address), MR_NO_MEM, " for service address");
133     ASSERT(NONNULL(target_path), MR_INTERNAL, " null target pathname");
134     ASSERT((strlen(target_path) < MAXPATHLEN), MR_ARG_TOO_LONG,
135            " target pathname");
136     ASSERT2(target_path[0] == '/', MR_NOT_UNIQUE,
137            " non-absolute pathname supplied \"%s\"", target_path);
138     sprintf(buf, "%s/%s.out", DCM_DIR, service);
139     pathname = strsave(buf);
140     ASSERT(NONNULL(pathname), MR_NO_MEM, " for pathname");
141     ASSERT(NONNULL(instructions), MR_NO_MEM, " for instructions");
142     ASSERT((strlen(instructions) < MAXPATHLEN), MR_ARG_TOO_LONG,
143            " instruction pathname");
144     
145     initialize();
146     com_err(whoami, 0, "starting update for %s", service_updated);
147     
148     /* open connection */
149     gdb_Options |= GDB_OPT_KEEPALIVE;
150     conn = start_server_connection(service_address, "");
151     if (!conn || (connection_status(conn) == CON_STOPPED)) {
152         com_err(whoami, connection_errno(conn),
153                 " can't connect to update %s", service_address);
154         return(MR_CANT_CONNECT);
155     }
156     
157     /* send authenticators */
158     code = send_auth(machine);
159     if (code) {
160         com_err(whoami, code, " authorization attempt to %s failed",
161                 service_updated);
162         goto update_failed;
163     }
164     
165     code = send_file(pathname, target_path, 1);
166     if (code)
167       goto update_failed;
168
169     /* send instructions for installation */
170     strcpy(buf, "/tmp/moira-update.XXXXXX");
171     mktemp(buf);
172     code = send_file(instructions, buf, 0);
173     if (code)
174       goto update_failed;
175
176     /* perform installation */
177     code = execute(buf);
178     if (code) {
179         com_err(whoami, code, " installation of %s failed, code = %d",
180                 service_updated, code);
181         goto update_failed;
182     }
183     
184     /* finished updates */
185     code = MR_SUCCESS;
186
187  update_failed:
188     send_quit();
189     conn = sever_connection(conn);
190     return(code);
191
192 #undef NONNULL
193 #undef ASSERT
194 }
195
196 send_auth(host_name)
197 char *host_name;
198 {
199     KTEXT_ST ticket_st;
200     KTEXT ticket = &ticket_st;
201     STRING data;
202     register int code;
203     int response;
204     int auth_version = 2;
205     
206     code = get_mr_update_ticket(host_name, ticket);
207     if (code) {
208         return(code);
209     }
210     STRING_DATA(data) = "AUTH_002";
211     MAX_STRING_SIZE(data) = 9;
212     code = send_object(conn, (char *)&data, STRING_T);
213     if (code) {
214         return(connection_errno(conn));
215     }
216     code = receive_object(conn, (char *)&response, INTEGER_T);
217     if (code) {
218         return(connection_errno(conn));
219     }
220     if (response) {
221         STRING_DATA(data) = "AUTH_001";
222         MAX_STRING_SIZE(data) = 9;
223         code = send_object(conn, (char *)&data, STRING_T);
224         if (code) {
225             return(connection_errno(conn));
226         }
227         code = receive_object(conn, (char *)&response, INTEGER_T);
228         if (code) {
229             return(connection_errno(conn));
230         }
231         if (response) {
232             return(response);
233         }
234         auth_version = 1;
235     }
236     STRING_DATA(data) = (char *)ticket->dat;
237     MAX_STRING_SIZE(data) = ticket->length;
238     code = send_object(conn, (char *)&data, STRING_T);
239     if (code) {
240         return(connection_errno(conn));
241     }
242     code = receive_object(conn, (char *)&response, INTEGER_T);
243     if (code) {
244         return(connection_errno(conn));
245     }
246     if (response) {
247         return(response);
248     }
249     
250     if (auth_version == 2) {
251         des_key_schedule sched;
252         C_Block enonce;
253
254         code = receive_object(conn, (char *)&data, STRING_T);
255         if (code) {
256             return(connection_errno(conn));
257         }
258         des_key_sched(&session, &sched);
259         des_ecb_encrypt(STRING_DATA(data), enonce, sched, 1);
260         STRING_DATA(data) = enonce;
261         code = send_object(conn, (char *)&data, STRING_T);
262         if (code) {
263             return(connection_errno(conn));
264         }
265         code = receive_object(conn, (char *)&response, INTEGER_T);
266         if (code) {
267             return(connection_errno(conn));
268         }
269         if (response) {
270             return(response);
271         }
272     }
273
274     return(MR_SUCCESS);
275 }
276
277 execute(path)
278     char *path;
279 {
280     int response;
281     STRING data;
282     register int code;
283     
284     string_alloc(&data, BUFSIZ);
285     sprintf(STRING_DATA(data), "EXEC_002 %s", path);
286     code = send_object(conn, (char *)&data, STRING_T);
287     if (code)
288         return(connection_errno(conn));
289     code = receive_object(conn, (char *)&response, INTEGER_T);
290     if (code)
291         return(connection_errno(conn));
292     if (response)
293       return(response);
294     return(MR_SUCCESS);
295 }
296
297 send_quit()
298 {
299     STRING str;
300     if (!conn)
301         return;
302     string_alloc(&str, 5);
303     (void) strcpy(STRING_DATA(str), "quit");
304     (void) send_object(conn, (char *)&str, STRING_T);
305     string_free(&str);
306 }
This page took 0.071271 seconds and 5 git commands to generate.