]> andersk Git - moira.git/blame - server/mr_scall.c
support type KERBEROS list members
[moira.git] / server / mr_scall.c
CommitLineData
a3cf6921 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
c801de4c 7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
a3cf6921 9 *
a3cf6921 10 */
11
12#ifndef lint
13static char *rcsid_sms_scall_c = "$Header$";
14#endif lint
15
c801de4c 16#include <mit-copyright.h>
57c08162 17#include <sys/types.h>
18#include <sys/stat.h>
a3cf6921 19#include <krb.h>
78849033 20#include <errno.h>
8165c536 21#include "query.h"
a3cf6921 22#include "sms_server.h"
23extern char buf1[];
24extern int nclients;
25extern char *whoami;
28222705 26extern char *malloc();
8165c536 27extern int errno;
a3cf6921 28
29extern void clist_delete(), do_auth(), do_shutdown();
30void do_call();
31
32/*
33 * Welcome to the (finite state) machine (highest level).
34 */
35void
36do_client(cp)
37 client *cp;
38{
57c08162 39 struct stat stbuf;
40
ed31e0d1 41 free_rtn_tuples(cp);
a3cf6921 42 if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
a36b5bd7 43 com_err(whoami, 0, "Closed connection (now %d client%s, %d new queries, %d old)",
f17535a4 44 nclients-1,
a36b5bd7 45 nclients!=2?"s":"",
46 newqueries,
47 oldqueries);
a3cf6921 48 clist_delete(cp);
57c08162 49 /* if we no longer have any clients, and we're supposed to
50 * go down, then go down now.
51 */
52 if ((dormant == AWAKE) && (nclients == 0) &&
53 (stat(SMS_MOTD_FILE, &stbuf) == 0)) {
54 com_err(whoami, 0, "motd file exists, slumbertime");
55 dormant = SLEEPY;
56 }
a3cf6921 57 return;
58 }
59 switch (cp->action) {
60 case CL_ACCEPT:
61 case CL_SEND:
62 /* Start recieving next request */
63 initialize_operation(cp->pending_op, sms_start_recv,
5dbd09a0 64 (char *)&cp->args, (int (*)())NULL);
a3cf6921 65 queue_operation(cp->con, CON_INPUT, cp->pending_op);
66 cp->action = CL_RECEIVE;
67 break;
68 case CL_RECEIVE:
69 /* Data is here. Process it & start it heading back */
70 do_call(cp); /* This may block for a while. */
de24f12d 71 sms_destroy_reply(cp->args);
72 cp->args = NULL;
a3cf6921 73 initialize_operation(cp->pending_op, sms_start_send,
5dbd09a0 74 (char *)&cp->reply, (int (*)())NULL);
a3cf6921 75 queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
76 cp->action = CL_SEND;
77 break;
78 }
79}
80
a3cf6921 81char *procnames[] = {
82 "noop",
83 "auth",
84 "shutdown",
78849033 85 "query",
630e8323 86 "access",
57c08162 87 "dcm",
88 "motd",
630e8323 89};
90
a3cf6921 91
92void
93do_call(cl)
94 client *cl;
95{
96 int pn;
97 cl->reply.sms_argc = 0;
98 cl->reply.sms_status = 0;
a36b5bd7 99 cl->reply.sms_version_no = cl->args->sms_version_no;
a3cf6921 100 if (((pn = cl->args->sms_procno) < 0) ||
101 (pn > SMS_MAX_PROC)) {
102 com_err(whoami, 0, "procno out of range");
103 cl->reply.sms_status = SMS_UNKNOWN_PROC;
104 return;
105 }
630e8323 106 if (log_flags & LOG_ARGS)
a36b5bd7 107 log_args(procnames[pn], cl->args->sms_version_no,
108 cl->args->sms_argc, cl->args->sms_argv);
630e8323 109 else if (log_flags & LOG_REQUESTS)
f17535a4 110 com_err(whoami, 0, "%s", procnames[pn]);
a3cf6921 111
57c08162 112 if ((dormant == ASLEEP || dormant == GROGGY) &&
113 pn != SMS_NOOP && pn != SMS_MOTD) {
114 cl->reply.sms_status = SMS_DOWN;
115 if (log_flags & LOG_RES)
116 com_err(whoami, SMS_DOWN, "(query refused)");
117 return;
118 }
119
a3cf6921 120 switch(pn) {
121 case SMS_NOOP:
122 cl->reply.sms_status = 0;
a3cf6921 123 return;
3630192b 124
a3cf6921 125 case SMS_AUTH:
126 do_auth(cl);
127 return;
78849033 128
129 case SMS_QUERY:
a3cf6921 130 do_retr(cl);
131 return;
a3cf6921 132
3630192b 133 case SMS_ACCESS:
134 do_access(cl);
135 return;
136
a3cf6921 137 case SMS_SHUTDOWN:
138 do_shutdown(cl);
139 return;
8165c536 140
141 case SMS_DO_UPDATE:
a36b5bd7 142 trigger_dcm(0, 0, cl);
8165c536 143 return;
57c08162 144
145 case SMS_MOTD:
146 get_motd(cl);
147 return;
a3cf6921 148 }
149}
150
ed31e0d1 151free_rtn_tuples(cp)
152 client *cp;
153{
154 register returned_tuples *temp;
155 for (temp=cp->first; temp && OP_DONE(temp->op); ) {
156 register returned_tuples *t1=temp;
157 temp = t1->next;
158 if (t1 == cp->last) cp->last = NULL;
28222705 159
ed31e0d1 160 sms_destroy_reply(t1->retval);
ed31e0d1 161 delete_operation(t1->op);
162 free(t1);
163 }
164 cp->first = temp;
165}
166
78849033 167retr_callback(argc, argv, p_cp)
28222705 168 register int argc;
169 register char **argv;
78849033 170 char *p_cp;
171{
172 register client *cp = (client *)p_cp;
78849033 173 /*
174 * This takes too much advantage of the fact that
175 * serialization of the data happens during the queue operation.
176 */
177 sms_params *arg_tmp = (sms_params *)db_alloc(sizeof(sms_params));
ed31e0d1 178 returned_tuples *tp = (returned_tuples *)
179 db_alloc(sizeof(returned_tuples));
28222705 180 register char **nargv = (char **)malloc(argc * sizeof(char *));
181 register int i;
ed31e0d1 182
78849033 183 OPERATION op_tmp = create_operation();
78849033 184
a36b5bd7 185 if (sms_trim_args(argc, argv) == SMS_NO_MEM) {
186 com_err(whoami, SMS_NO_MEM, "while trimming args");
187 }
630e8323 188 if (log_flags & LOG_RESP)
a36b5bd7 189 log_args("return: ", cp->args->sms_version_no, argc, argv);
630e8323 190
ed31e0d1 191 tp->op = op_tmp;
192 tp->retval = arg_tmp;
193 tp->next = NULL;
78849033 194
195 arg_tmp->sms_status = SMS_MORE_DATA;
a36b5bd7 196 arg_tmp->sms_version_no = cp->args->sms_version_no;
78849033 197 arg_tmp->sms_argc = argc;
28222705 198 arg_tmp->sms_argv = nargv;
199 for (i = 0; i < argc; i++) {
200 register int len = strlen(argv[i]) + 1;
201 nargv[i] = malloc(len);
202 bcopy(argv[i], nargv[i], len);
203 }
78849033 204 arg_tmp->sms_flattened = (char *)NULL;
205 arg_tmp->sms_argl = (int *)NULL;
ed31e0d1 206
207 if (cp->last) {
208 cp->last->next = tp;
209 cp->last = tp;
210 } else {
211 cp->last = cp->first = tp;
212 }
213
78849033 214 reset_operation(op_tmp);
215 initialize_operation(op_tmp, sms_start_send, (char *)arg_tmp,
216 (int (*)())NULL);
217 queue_operation(cp->con, CON_OUTPUT, op_tmp);
218}
219
de24f12d 220list_users(callbk, callarg)
221 int (*callbk)();
222 char *callarg;
223{
224 char *argv[6];
225 char buf[30];
226 char buf1[30];
227 int i;
228 extern client **clients;
229 extern char *inet_ntoa();
230 char *cp;
231 char *index();
232 char *ctime();
233
234 for (i = 0; i < nclients; i++) {
235 register client *cl = clients[i];
236 if (cl->clname)
237 argv[0] = cl->clname;
238 else argv[0] = "unauthenticated";
239
240 argv[1] = inet_ntoa(cl->haddr.sin_addr);
241 argv[2] = buf;
242 sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
243 argv[3] = ctime(&cl->last_time_used);
244 cp = index(argv[3], '\n');
245 if (cp) *cp = '\0';
246 argv[4] = buf1;
247 sprintf(buf1, "[#%d]", cl->id);
248 (*callbk)(5, argv, callarg);
249 }
250 return 0;
251}
78849033 252
a3cf6921 253do_retr(cl)
de24f12d 254 register client *cl;
a3cf6921 255{
de24f12d 256 register char *queryname;
257
78849033 258 cl->reply.sms_argc = 0;
259 cl->reply.sms_status = 0;
630e8323 260
de24f12d 261 queryname = cl->args->sms_argv[0];
262
a36b5bd7 263 if (cl->args->sms_version_no == SMS_VERSION_2)
264 newqueries++;
265 else
266 oldqueries++;
267
de24f12d 268 if (strcmp(queryname, "_list_users") == 0)
269 cl->reply.sms_status = list_users(retr_callback, (char *)cl);
270 else {
271 cl->reply.sms_status =
272 sms_process_query(cl,
273 cl->args->sms_argv[0],
274 cl->args->sms_argc-1,
275 cl->args->sms_argv+1,
276 retr_callback,
277 (char *)cl);
278 }
630e8323 279 if (log_flags & LOG_RES)
280 com_err(whoami, 0, "Query complete.");
a3cf6921 281}
78849033 282
3630192b 283do_access(cl)
284 client *cl;
285{
286 cl->reply.sms_argc = 0;
630e8323 287
3630192b 288 cl->reply.sms_status =
289 sms_check_access(cl,
290 cl->args->sms_argv[0],
291 cl->args->sms_argc-1,
292 cl->args->sms_argv+1);
293
294 com_err(whoami, 0, "Access check complete.");
295}
8165c536 296
a36b5bd7 297
298/* trigger_dcm is also used as a followup routine to the
299 * set_server_host_override query, hence the two dummy arguments.
300 */
301
8165c536 302struct query pseudo_query = {
303 "trigger_dcm",
304 "tdcm",
305};
306
a36b5bd7 307trigger_dcm(dummy0, dummy1, cl)
308 int dummy0, dummy1;
8165c536 309 client *cl;
310{
311 register int pid;
312
313 cl->reply.sms_argc = 0;
314
315 if (cl->reply.sms_status = check_query_access(&pseudo_query, 0, cl) )
a36b5bd7 316 return(cl->reply.sms_status);
8165c536 317
318 pid = vfork();
319 switch (pid) {
320 case 0:
9ddf3daa 321 for (dummy0 = getdtablesize() - 1; dummy0 > 2; dummy0--)
322 close(dummy0);
a36b5bd7 323 execl("/u1/sms/bin/startdcm", "startdcm", 0);
8165c536 324 exit(1);
325
326 case -1:
327 cl->reply.sms_status = errno;
a36b5bd7 328 return(0);
8165c536 329
330 default:
a36b5bd7 331 return(0);
8165c536 332 }
333}
334
57c08162 335
336get_motd(cl)
337client *cl;
338{
339 FILE *motd;
340 char buffer[1024];
341 char *arg[1];
342
343 arg[0] = buffer;
344 cl->reply.sms_status = 0;
345 motd = fopen(SMS_MOTD_FILE, "r");
346 if (motd == NULL) return;
347 fgets(buffer, sizeof(buffer), motd);
348 fclose(motd);
349 retr_callback(1, arg, cl);
350 cl->reply.sms_status = 0;
351}
This page took 0.294524 seconds and 5 git commands to generate.